这让我抓狂,我已经尝试了所有的东西,虽然有一件事情起作用,但最终并不是一个好的解决方案.首先是我的代码.
apps_grid.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <GridView android:id="@+id/appGrid" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/ic_launcher_background" android:horizontalSpacing="4dp" android:numColumns="4" android:paddingTop="10dp" android:stretchMode="columnWidth" android:verticalSpacing="15dp"/> </LinearLayout>
app_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <ImageView android:id="@+id/icon" android:layout_width="54dp" android:layout_height="54dp" android:layout_gravity="center_horizontal" android:src="@mipmap/ic_launcher" /> <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginTop="5dp" android:ellipsize="end" android:gravity="center" android:paddingEnd="15dp" android:paddingStart="15dp" android:singleLine="true" android:text="title" android:textColor="@android:color/white" android:textSize="14sp" /> </LinearLayout>
activity_main.xml中
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="45dp" android:fillViewport="true" app:layout_behavior="@string/appbar_scrolling_view_behavior" />
AppModel.java
public class AppModel { private String label; private String pkg; private Drawable mIcon; public AppModel(String name,String pkg,Drawable icon) { this.label = name; this.pkg = pkg; this.mIcon = icon; } public AppModel(String name) { this.label = name; } public String getLabel() { return this.label; } public String getPkg() { return this.pkg; } public Drawable getIcon() { return mIcon; } }
AppListAdapter.java
public class AppListAdapter extends BaseAdapter { private ArrayList<AppModel> apps; private LayoutInflater layoutInflater; public AppListAdapter(Context context,ArrayList<AppModel> apps) { this.apps = apps; this.layoutInflater = LayoutInflater.from(context); } @Override public int getCount() { return apps.size(); } @Override public long getItemId(int position) { return 0; } @Override public Object getItem(int position) { AppModel app = apps.get(position); if(app == null) { return null; } return app; } @Override public View getView(int position,View convertView,ViewGroup parent) { AppModel app = apps.get(position); if (convertView == null) { convertView = layoutInflater.inflate(R.layout.app_item,null); } if(app == null) { return convertView; } ((TextView)convertView.findViewById(R.id.text)).setText(app.getLabel()); return convertView; } }
TestPagerAdapter.java
public class TestPagerAdapter extends PagerAdapter { private Context mContext; private LayoutInflater inflater; private ArrayList<AppModel> apps; private int perPage = 12; public TestPagerAdapter(Context context) { this.mContext = context; this.inflater = LayoutInflater.from(context); } @Override public Object instantiateItem(ViewGroup parent,int position) { ViewGroup layout = (ViewGroup) inflater.inflate(R.layout.apps_grid,parent,false); ArrayList<AppModel> pageApps = getAppsForPage(position); if(pageApps == null) { return layout; } final GridView appGrid = (GridView) layout.findViewById(R.id.appGrid); final AppListAdapter gridAdapter = new AppListAdapter(mContext,pageApps); appGrid.setVerticalScrollBarEnabled(false); appGrid.setAdapter(gridAdapter); parent.addView(layout); return layout; } @Override public void destroyItem(ViewGroup parent,int position,Object view) { parent.removeView((View) view); } @Override public int getCount() { if(apps != null) { return (int) Math.ceil((double) apps.size() / perPage); } else { return 0; } } @Override public boolean isViewFromObject(View view,Object object) { return view == object; } public void setData(ArrayList<AppModel> data) { if(data != null) { this.apps = data; } } public ArrayList<AppModel> getAppsForPage(int page) { if(apps == null) { return null; } int size = apps.size(); int offset = getOffset(page); ArrayList<AppModel> pageApps = new ArrayList<AppModel>(size); for(int i = 0; i < perPage; i++) { if(offset+i < size) { pageApps.add(apps.get(offset+i)); } } return pageApps; } public int getOffset(int page) { return perPage*page; } }
MainActivity.java
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager); TestPagerAdapter mPAdapter = new TestPagerAdapter(this); viewPager.setAdapter(mPAdapter); ArrayList<AppModel> items = new ArrayList<AppModel>(20); for(int i=0;i<20;i++) { AppModel app = new AppModel(""+i); items.add(app); } mPAdapter.setData(items); mPAdapter.notifyDataSetChanged(); }
所以,这是我尝试过的:
我用RecyclerView替换了GridView.
在EVERY View上添加了所有这些属性
android:clickable="false" android:contextClickable="false" android:defaultFocusHighlightEnabled="false" android:focusable="false" android:focusableInTouchMode="false" android:focusedByDefault="false" android:isScrollContainer="false" android:longClickable="false" android:nestedScrollingEnabled="false" android:overScrollMode="never" android:touchscreenBlocksFocus="false"
在GridView上覆盖OnTouchListener(以及许多其他)并返回true.
可能尝试了一些我现在记不住的其他事情了.
唯一有效的是在GridView上设置android:filterTouchesWhenObscured =“true”属性,而其他一些应用程序视图位于顶部(所以条件“WhenObscured”满足)
当我尝试这个时,我的ViewPager开始非常流畅地滚动,在其他情况下它有时不会滚动(可能是当GridView拦截它时).
请注意,GridView中的项目必须是可点击的.
UPDATE
https://github.com/mpa4hu/GridViewPager这是项目的github链接,用类似于这张图片的手势模拟向前和向后滚动的问题
解决方法
RecyclerView是作为ListView改进创建的,所以是的,您可以使用ListView控件创建附加列表,但使用RecyclerView更容易:
在向上/向下滚动时重用单元格 – 这可以通过在listView适配器中实现View Holder来实现,但它是可选的,而在RecycleView中它是编写适配器的默认方式.
将列表与其容器分离 – 因此您可以使用设置LayoutManager在运行时轻松地将列表项放在不同的容器(linearLayout,gridLayout)中.
例:
mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view); mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); //or mRecyclerView.setLayoutManager(new GridLayoutManager(this,2));//number of columns in a grid layout
有关RecyclerView的更多信息,但我认为这些是主要的.
因此,总而言之,RecyclerView是一种更灵活的控制,用于处理“列表数据”,遵循关注委托模式,并为自己留下一个任务 – 回收项目.
你可以在这里参考它的优点:RecyclerView over ListView