我卡住試圖重新加載ListView
內ListFragment
。刷新是通過我在FragmentDialog
中創建的偵聽器調用的。 reloadItems方法已正確調用,並且我已驗證項目列表在變量中已正確更新。重新加載列表視圖從內聯類
這似乎是一個簡單的事情要做,但我卡住了。 ListView從來沒有實際更新,但我相信它與使用的Context
有關。
onClick
通過使用屬性設置的ListView
行的按鈕調用。
解決方案 的問題是,我的選項卡適配器getItem(...)
被unexpectantly再次呼籲創建時AlertDialog
被而且由於我可憐的代碼,它重新實例化的標籤,並刷新從未發生過的可見片段。 (請參見最後的原始代碼)
一旦發現此問題(請參閱接受的答案),我可以通過重新修改代碼選項卡適配器來修復它以維護引用。這是我的工作選項卡適配器,適用於ViewPager
以防萬一對任何人有幫助。
public class TabsAdapter extends FragmentPagerAdapter implements ActionBar.TabListener, ViewPager.OnPageChangeListener {
private final Context mContext;
private final ActionBar mActionBar;
private final ViewPager mViewPager;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
private ArrayList<Fragment> mFragments = new ArrayList<Fragment>();
static final class TabInfo {
private final Class<?> mClass;
private final Bundle mArgs;
TabInfo(Class<?> _class, Bundle _args) {
mClass = _class;
mArgs = _args;
}
public String getClassName() {
return mClass.getName();
}
public Bundle getArgs() {
return mArgs;
}
}
public TabsAdapter(Activity activity, ViewPager pager) {
super(activity.getFragmentManager());
mContext = activity;
mActionBar = activity.getActionBar();
mViewPager = pager;
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
TabInfo info = new TabInfo(clss, args);
tab.setTag(info);
tab.setTabListener(this);
mTabs.add(info);
mActionBar.addTab(tab);
Fragment fragment = Fragment.instantiate(mContext, info.getClassName(), info.getArgs());
mFragments.add(fragment);
notifyDataSetChanged();
}
@Override
public int getCount() {
return mTabs.size();
}
@Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
public void onPageSelected(int position) {
mActionBar.setSelectedNavigationItem(position);
}
public void onPageScrollStateChanged(int state) {
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
Object tag = tab.getTag();
for (int i = 0; i < mTabs.size(); i++) {
if (mTabs.get(i) == tag) {
mViewPager.setCurrentItem(i);
}
}
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
}
的解決方案最終
活動
public class MyActivity extends Activity {
// unrelated code removed
public void onClick(View v) {
// onClick is called via a button on a list item
MyFragment sf = (MyFragment)mTabsAdapter.getItem(0);
sf.myClick(v, getFragmentManager());
}
}
MyFragment
public class MyFragment extends ListFragment {
static final String TAG = "StatusFragment";
private ArrayList<MyObject> mItems = null;
AlarmDataSource datasource;
StatusAdapter mAdapter;
public void reloadItems(Context context) {
Log.d(TAG, "reloadItems");
datasource = new MyObjectDataSource(context);
datasource.open();
mItems = new ArrayList<MyObject>();
ArrayList<MyObject> active = (ArrayList<MyObject>)datasource.getAllEnabled();
for (int i = 0; i < active.size(); i++) {
MyObject next = active.get(i);
mItems.add(next);
}
mAdapter = new StatusAdapter(
context,
R.layout.status_list_item,
mItems);
// set a breakpoint and this is called when called from
// statusOptionDialogClose below. Here mAdapter DOES HAVE updated items
// inside. However getView within the adaper is NOT called
setListAdapter(mAdapter);
datasource.close();
}
public void myClick(View v, FragmentManager manager) {
StatusOptionDialog sod = StatusOptionDialog.newInstance(v.getContext());
sod.setStatusOptionDialogListener(new StatusOptionDialogListener() {
public void statusOptionDialogClose(Context context) {
// this is correctly called when dialog closed
// context is the same as sent in with newInstance above.
reloadItems(context);
}
});
sod.show(manager, "StatusOptionDialog");
}
}
任何人看到什麼歪?我嘗試了很多不同的方式,但沒有任何工作。
注意我也試過mAdapter.notifyDataSetChanged()
更新時,也不起作用。今天晚些時候我會嘗試逐步瀏覽Android SDK代碼,看看是否可以在那裏精確定位數據,以防數據沒有進入適配器或有些奇怪。
更新我追查了更多的問題。看起來在setListItem(mAdapter)
與mAdapter成功更新了項目後,不會調用適配器getView(...)
。
更新#2我已經發布reloadItems(...)
函數,我已經蒸餾成最簡單的代碼有問題。 setListAdapter(...)
使用已更新項目的更新適配器調用。但是getView(...)
永遠不會調用reloadItems(...)
通過statusOptionDialogClose(...)
調用如果我殺死應用程序並重新啓動它,ListView顯示更新的數據。只是在再次調用reloadItem時不刷新。
適配器
public class StatusAdapter extends ArrayAdapter<MyObject> {
private Context mContext;
private int mRes;
private ArrayList<MyObject> mItems;
public StatusAdapter(Context context, int textViewResourceId, ArrayList<MyObject> items) {
super(context, textViewResourceId, items);
this.mItems = items;
this.mRes = textViewResourceId;
this.mContext = context;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(mRes, null);
}
Alarm a = mItems.get(position);
if (a != null) {
// fills out list item
}
return v;
}
@Override
public int getCount() {
return mItems.size();
}
public void setNewList(ArrayList<Alarm> items) {
this.mItems = items;
}
}
選項卡適配器這是用來使ViewPager
和選項卡。
public class TabsAdapter extends FragmentPagerAdapter implements
ActionBar.TabListener, ViewPager.OnPageChangeListener {
private final Context mContext;
private final ActionBar mActionBar;
private final ViewPager mViewPager;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
static final class TabInfo {
private final Class<?> clss;
private final Bundle args;
TabInfo(Class<?> _class, Bundle _args) {
clss = _class;
args = _args;
}
}
public TabsAdapter(Activity activity, ViewPager pager) {
super(activity.getFragmentManager());
mContext = activity;
mActionBar = activity.getActionBar();
mViewPager = pager;
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
TabInfo info = new TabInfo(clss, args);
tab.setTag(info);
tab.setTabListener(this);
mTabs.add(info);
mActionBar.addTab(tab);
notifyDataSetChanged();
}
@Override
public int getCount() {
return mTabs.size();
}
@Override
public Fragment getItem(int position) {
TabInfo info = mTabs.get(position);
return Fragment.instantiate(mContext, info.clss.getName(), info.args);
}
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
public void onPageSelected(int position) {
mActionBar.setSelectedNavigationItem(position);
}
public void onPageScrollStateChanged(int state) {
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
Object tag = tab.getTag();
for (int i = 0; i < mTabs.size(); i++) {
if (mTabs.get(i) == tag) {
mViewPager.setCurrentItem(i);
}
}
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
}
謝謝你的回覆。我發佈了我使用的選項卡適配器,以防使用它。我不確定getItem(...)是否正確實現。我在那裏放置了一個斷點,它被稱爲超過預期。 – Kirk 2012-08-13 15:44:41
你說得對。該選項卡適配器正在重新創建片段。我重寫了它,並修復了它。哇,花了很多時間來解決這個問題。總是有些愚蠢的東西阻止我。 – Kirk 2012-08-13 16:30:07
很高興幫助!對於它的價值,我可以告訴你,我有這種懷疑,因爲我在不同時間犯了同樣的錯誤:) – Joe 2012-08-13 16:52:51