我有一个ViewPager
托管在一个片段中,该片段托管了两个ListFragments
,这些片段由从SQLite查询返回的Cursor
填充。最近,我在操作栏上添加了一个微调器,该微调器将允许用户对ViewPager
中的列表进行排序。但是,每次选择微调框时,即使当前显示第一个列表,也仅对第二个列表进行排序。似乎ViewPager
不能跟踪当前显示的ListFragment
。
我曾尝试在适配器中使用n getItemPosition
覆盖otifyDataSetChanged
,但这无济于事。我尝试将当前活动片段的位置缓存在onAttach()
中也无济于事。我还尝试使用适配器实现的OnSortChanged
接口来尝试重新创建ListFragments
。我真的很茫然。这是我当前的代码:
我的主要片段:
public class BeerMenuFragment extends SherlockFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.beer_menu_fragment, container,
false);
ViewPager pager = (ViewPager) view.findViewById(R.id.beer_pager);
pager.setAdapter(buildAdapter());
return view;
}
private PagerAdapter buildAdapter() {
return (new BeerMenuAdapter(getChildFragmentManager()));
}
}
我的
FragmentPagerAdapter
:public class BeerMenuAdapter extends FragmentPagerAdapter {
private final int NUM_ITEMS = 2;
public BeerMenuAdapter(FragmentManager fm) {
super(fm);
}
/*
* (non-Javadoc)
*
* @see android.support.v4.view.PagerAdapter#getPageTitle(int)
*/
@Override
public CharSequence getPageTitle(int position) {
return BeerListFragment.getTitle(position);
}
@Override
public int getCount() {
return NUM_ITEMS;
}
@Override
public Fragment getItem(int position) {
return BeerListFragment.newInstance(position);
}
}
最后,
ListFragment
:public class BeerListFragment extends SherlockListFragment implements
OnNavigationListener {
private static final String KEY_POSITION = "position";
private static final String KEY_SPINNER = "ab_spinner";
private IconicAdapter adapter;
private static final String[] LABELS = { "Newest First", "Oldest First",
"Alphabetical" };
private Context ctxt;
private int mShowItems;
private Cursor data;
private boolean synthetic = true;
static BeerListFragment newInstance(int position) {
BeerListFragment frag = new BeerListFragment();
Bundle args = new Bundle();
args.putInt(KEY_POSITION, position);
frag.setArguments(args);
return (frag);
}
static String getTitle(int position) {
String header = "Draft";
switch (position) {
case 0:
header = "Draft";
break;
case 1:
header = "Bottle";
break;
}
return (header);
}
/*
* (non-Javadoc)
*
* @see
* android.support.v4.app.ListFragment#onCreateView(android.view.LayoutInflater
* , android.view.ViewGroup, android.os.Bundle)
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View result = inflater.inflate(R.layout.menu_list_fragment, container,
false);
ctxt = getActivity().getApplicationContext();
SQLiteDatabase db = DatabaseHelper.getInstance(ctxt)
.getReadableDatabase();
SherlockFragmentActivity activity = getSherlockActivity();
ArrayAdapter<String> show = null;
ActionBar bar = activity.getSupportActionBar();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
show = new ArrayAdapter<String>(bar.getThemedContext(),
android.R.layout.simple_spinner_item, LABELS);
} else {
show = new ArrayAdapter<String>(activity,
android.R.layout.simple_spinner_item, LABELS);
}
show.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
bar.setListNavigationCallbacks(show, this);
if (savedInstanceState != null) {
bar.setSelectedNavigationItem(savedInstanceState
.getInt(KEY_SPINNER));
}
data = getBeerMenuDbData(db, mShowItems);
// set up list adapter
adapter = new IconicAdapter(ctxt, data);
setListAdapter(adapter);
return (result);
}
private Cursor getBeerMenuDbData(SQLiteDatabase db, int showItems) {
String order;
String WHERE;
switch (showItems) {
case 1: // Oldest First
order = DbContract.BeerEntry.COLUMN_MODIFIED + " ASC";
break;
case 2: // Alphabetical
order = DbContract.BeerEntry.COLUMN_TITLE + " ASC";
break;
default: // Newest first
order = DbContract.BeerEntry.COLUMN_MODIFIED + " DESC";
break;
}
String[] COLUMNS = { DbContract.BeerEntry._ID,
DbContract.BeerEntry.COLUMN_TITLE,
DbContract.BeerEntry.COLUMN_MODIFIED };
WHERE = "serving='" + getTitle(getArguments().getInt(KEY_POSITION, -1))
+ "'";
return db.query(DbContract.BeerEntry.TABLE_NAME, COLUMNS, WHERE, null,
null, null, order);
}
class IconicAdapter extends CursorAdapter {
LayoutInflater inflater;
IconicAdapter(Context context, Cursor data) {
super(context, data, 0);
inflater = LayoutInflater.from(context);
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
String dateString = cursor.getString(2);
String[] dateArray = new String[3];
TextView beerName = (TextView) view.findViewById(R.id.beerName);
TextView date = (TextView) view.findViewById(R.id.drinkDate);
RatingBar rb = (RatingBar) view.findViewById(R.id.ratingBar1);
beerName.setText(cursor.getString(1));
if (!dateString.isEmpty()) {
dateArray = dateString.split("-");
date.setText(dateArray[1] + "/" + dateArray[2] + "/"
+ dateArray[0]);
} else {
date.setText(dateString);
}
rb.setRating((float) Math.random() * 5.0f);
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return inflater
.inflate(R.layout.beer_club_list_item, parent, false);
}
}
/*
* (non-Javadoc)
*
* @see android.support.v4.app.Fragment#onDestroy()
*/
@Override
public void onDestroy() {
super.onDestroy();
((CursorAdapter) getListAdapter()).getCursor().close();
}
@Override
public boolean onNavigationItemSelected(int itemPosition, long itemId) {
if (synthetic) {
synthetic = false;
return true;
}
mShowItems = itemPosition;
SQLiteDatabase db = DatabaseHelper.getInstance(ctxt)
.getReadableDatabase();
Cursor newData = getBeerMenuDbData(db, mShowItems);
adapter.changeCursor(newData);
return true;
}
@Override
public void onSaveInstanceState(Bundle outState) {
outState.putInt(KEY_SPINNER, getSherlockActivity()
.getSupportActionBar().getSelectedNavigationIndex());
}
}
在此先感谢您的帮助!
最佳答案
因此,您的问题是您正在bar.setListNavigationCallbacks(show, this)
内调用BeerListFragment
。在BeerListFragment
中创建第一个ViewPager
时,会将其自身设置为导航选择的回调。然后,当创建第二个BeerListFragment
(ViewPager
s在当前可见页面的左右两侧恢复页面)时,它将自身设置为导航选择的回调,并覆盖第一个BeerListFragment
,现在将不再获取onNavigationItemSelected
回调。
所有这些都会导致您所看到的行为,最后一个调用BeerListFragment
的bar.setListNavigationCallbacks
将是唯一接收onNavigationItemSelected
回调的人。这就是为什么仅对第二个BeerListFragment
进行排序的原因。
为了解决这个问题,我建议您做一些事情:
管理在BeerMenuFragment
中为导航选择设置回调,并将结果传递给处于“活动状态”(在Fragment
中)的子级onResume
。为此,您需要使用answers here之一。
存储最新应用的排序选项,并检入每个onResume
的BeerListFragment
以查看其排序是否匹配,如果不匹配,则应用排序。
这将确保您的所有排序都应用于ViewPager
中的所有页面,无论它们在应用排序时是否显示。
关于android - ViewPager FragmentPagerAdapter仅更新onNavigationItemSelected的最后一个 fragment ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16239512/