我已经看到一些关于使用ViewPager使GridView跨越多个“页面”的问题,但我想要做的是将ViewPager作为GridView中的项目。
这是一个简单的图片,试图说明我之后的用户界面:image desired outcome
这显示了一个2项宽的网格视图(垂直扩展),每个项目都有一个标题和一个具有多个页面的视图寻呼机,能够以一种很好的动画方式“向左/向右”滑动到下一页。
下面是一个非常简化的版本的代码,它显示了我遇到的问题,我绕过了使用ArrayAdapters时你会做的一些正常事情:
MainActivity.java
package com.example.viewpageringridviewtest;
import java.util.ArrayList;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import android.widget.TextView;
public class MainActivity extends FragmentActivity {
private static final String TAG = "VPinGVTest";
private ArrayList<String> mBoxes = new ArrayList<String>();
private ArrayList<String> mItems = new ArrayList<String>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
for (int i = 1; i <= 1; i++) mBoxes.add("Box " + i);
for (int i = 1; i <= 3; i++) mItems.add("Page " + i);
GridView grid = (GridView) findViewById(R.id.grid);
GridAdapter adapter = new GridAdapter(this, R.layout.grid_item);
grid.setAdapter(adapter);
}
private class GridAdapter extends ArrayAdapter<String> {
private LayoutInflater mLayoutInflater;
public GridAdapter(Context context, int resource) {
super(context, resource);
mLayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return mBoxes.size();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Log.d(TAG, "GridAdapter::getView(" + position + ")");
View v = convertView;
Holder holder = null;
if (v == null) {
Log.d(TAG, "Inflating R.layout.grid_item");
v = mLayoutInflater.inflate(R.layout.grid_item, null);
holder = new Holder(v);
v.setTag(holder);
} else {
Log.d(TAG, "Recycling view");
holder = (Holder) v.getTag();
}
holder.populate(position);
return v;
}
private class Holder {
private View mRow;
private TextView mTitle;
private ViewPager mViewPager;
private ItemPagerAdapter mItemPagerAdapter;
public Holder(View v) {
mRow = v;
mTitle = (TextView) mRow.findViewById(R.id.txt_title);
mViewPager = (ViewPager) mRow.findViewById(R.id.pager);
mItemPagerAdapter = new ItemPagerAdapter(getSupportFragmentManager());
}
public void populate(int position) {
mTitle.setText(mBoxes.get(position));
mViewPager.setAdapter(mItemPagerAdapter);
}
}
}
private class ItemPagerAdapter extends FragmentPagerAdapter {
public ItemPagerAdapter(FragmentManager fm) {
super(fm);
Log.i(TAG, "Creating new ItemPagerAdapter");
}
@Override
public Fragment getItem(int position) {
Log.d(TAG, "Creating fragment for item in position " + position);
return new ItemFragment(mItems.get(position));
}
@Override
public int getCount() {
return mItems.size();
}
}
private class ItemFragment extends Fragment {
private String mItem;
public ItemFragment(String item) {
mItem = item;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.d(TAG, "Inflating layout R.layout.grid_item_page");
View view = inflater.inflate(R.layout.grid_item_page, container, false);
((TextView) view.findViewById(R.id.txt_page_title)).setText(mItem);
return view;
}
}
}
activity_main.xml中
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<GridView
android:id="@+id/grid"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="2"
android:columnWidth="140dp"
android:stretchMode="columnWidth"
android:animateLayoutChanges="true"
android:verticalSpacing="7dp"
android:horizontalSpacing="7dp" />
</RelativeLayout>
grid_item.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"
android:background="#FF0000">
<TextView
android:id="@+id/txt_title"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<!-- View Pager -->
<android.support.v4.view.ViewPager
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/holo_blue_dark" />
</LinearLayout>
grid_item_page.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" >
<TextView
android:id="@+id/txt_page_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
以下是输出actual outcome的图像。正如您所看到的那样,View寻呼机根本没有出现,就好像它没有任何内容一样。使用上面的代码,这里是我得到的日志消息:
D/VPinGVTest(2134): GridAdapter::getView(0)
D/VPinGVTest(2134): Inflating R.layout.grid_item
I/VPinGVTest(2134): Creating new ItemPagerAdapter
D/VPinGVTest(2134): GridAdapter::getView(0)
D/VPinGVTest(2134): Recycling view
D/VPinGVTest(2134): GridAdapter::getView(0)
D/VPinGVTest(2134): Recycling view
D/VPinGVTest(2134): Creating fragment for item in position 0
D/VPinGVTest(2134): Creating fragment for item in position 1
D/VPinGVTest(2134): Inflating layout R.layout.grid_item_page
D/VPinGVTest(2134): Inflating layout R.layout.grid_item_page
D/VPinGVTest(2134): GridAdapter::getView(0)
D/VPinGVTest(2134): Inflating R.layout.grid_item
I/VPinGVTest(2134): Creating new ItemPagerAdapter
D/VPinGVTest(2134): GridAdapter::getView(0)
D/VPinGVTest(2134): Recycling view
D/VPinGVTest(2134): GridAdapter::getView(0)
D/VPinGVTest(2134): Recycling view
D/VPinGVTest(2134): GridAdapter::getView(0)
D/VPinGVTest(2134): Recycling view
因此它多次调用getView(0),第一次创建寻呼机适配器并最终创建片段。进一步调用getView(0)回收视图,除了重新膨胀布局的第4个视图,创建了寻呼机适配器但没有创建片段。
感谢任何人对如何解决这个问题有任何想法,或者是否有更好的解决方案我可以使用。