CBe*_*4ok 6 android gridview android-gridview android-viewpager
我实现了一个GridView内部PageViewer,但滚动并不像它应该的那样平滑.里面GridView的意见是拦截的接触.
这让我抓狂,我已经尝试了所有的东西,虽然有一件事情起作用,但最终并不是一个好的解决方案.首先是我的代码.
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>
Run Code Online (Sandbox Code Playgroud)
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>
Run Code Online (Sandbox Code Playgroud)
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"
/>
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
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();
}
Run Code Online (Sandbox Code Playgroud)
所以,这是我尝试的:我替换GridView为RecyclerView.在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"
Run Code Online (Sandbox Code Playgroud)
重写OnTouchListener(和许多其他)GridView并返回true.可能尝试了一些我现在记不住的其他事情了.
唯一有用的是设置android:filterTouchesWhenObscured="true"属性,GridView而其他一些应用程序视图在顶部(所以条件"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
Run Code Online (Sandbox Code Playgroud)
关于RecyclerView的内容还有很多,但我觉得主要就是这几点。
因此,总而言之,RecyclerView 是一种更灵活的控件,用于处理“列表数据”,它遵循关注点委托模式,并且只为自己留下一个任务 - 回收项目。
你可以在这里参考它的优点:RecyclerView over ListView