Android ListView 未 displayed/refreshing 且 getView 无法正常工作
Android ListView not being displayed/refreshing and getView not working properly
Objective: 我有一个 activity 并且在两个片段中。 ideia是将两个fragments进行通信,选择一个category并更新其item list.On activity load,一个category是默认settle的。
问题: 在 activity 加载时,ItemsFragment 没有 display/update itemsLisView。 ItemAdapter 的 getView 方法也只被调用了两次,即使列表有五个项目。
事实:
- 项目列表在传递给适配器之前已正确完成
- 断点代码,不确定为什么或是否重要,ItemsFragment rendered/called 在 CategoriesFragments 之前。我发现这很奇怪,因为 CategoriesFragments 位于 ItemsFragment 之上。这就是我写
if (getArguments() != null)
的原因。在我得到空指针异常之前。
研究:关于这两个主题有很多问题。
- Android ListView not refreshing after notifyDataSetChanged with data as Map
- ListFragment Not Rendering and getView() in Adapter Not Being Called
- Android getView() not being called properly?
- BaseAdapter notifyDatasetChanged() called but getView() is never called
这些是我经历过的一些 link 个例子(数以千计),试图为我的案例找到解决方案。不幸的是 none 他们成功了。
我已经被这个问题困扰将近 5 天了,我想我在这里遗漏了一些 Android 概念。这与 Java 编程无关,至少我希望如此。
问题:
- 为什么 ItemsFragment 在 activity 加载时不显示项目列表? (这可能解决了更新问题)
- 为什么 ItemAdapter 只调用 getView 两次,即使 Items List 正确地给他更多的项目?
如需任何进一步的信息,请不要介意询问。
在此先感谢您的帮助。
编辑 - MCVE:
activity_triple_list:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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:fitsSystemWindows="true"
tools:context=".controller.activities.Lists">
<include layout="@layout/content_triple_list" />
</android.support.design.widget.CoordinatorLayout>
content_triple_list:
<?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.support.v4.view.ViewPager
android:id="@+id/listsPager"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.PagerTabStrip
android:id="@+id/pager_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:paddingBottom="4dp"
android:paddingTop="4dp" />
</android.support.v4.view.ViewPager>
</LinearLayout>
fragment_categories:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/categoriesFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TableLayout
android:id="@+id/categoriesTable"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:stretchColumns="4">
<TableRow
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_marginTop="5dp"
android:gravity="center_horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="0"
android:layout_marginLeft="13dp"
android:layout_marginRight="13dp"
android:orientation="vertical">
<TextView
android:id="@+id/category1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="CATEGORY 1"
android:textAlignment="center"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
</TableRow>
</TableLayout>
</LinearLayout>
fragment_items:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@id/itemsFragment"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<ListView
android:id="@+id/itemsListView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:divider="@null" />
</LinearLayout>
content_row_choose_item:
<?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:background="@drawable/custom_row"
android:orientation="vertical"
android:paddingBottom="5dp"
android:paddingLeft="15dp"
android:paddingTop="5dp">
<TextView
android:id="@+id/itemName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TEST"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
custom_row:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:background="#2fff00">
<item android:drawable="@color/colorPrimary" android:state_pressed="true" /> <!-- pressed -->
</selector>
ApplicationUtils:
public final class ApplicationUtils extends Application {
private static Context context;
public void onCreate() {
super.onCreate();
ApplicationUtils.context = getApplicationContext();
}
public static Context getContext() {
return ApplicationUtils.context;
}
public static String getJavaPackageName() {
return ApplicationUtils.context.getPackageName();
}
public static Resources getAppResources() {
return getContext().getResources();
}
public static String getResouceName(Integer id) {
return getAppResources().getResourceName(id);
}
public static String getResourceString(Integer id) {
return getAppResources().getString(id);
}
public static int getResourceId(String variableName, String resourceName, String packageName) {
try {
return getContext().getResources().getIdentifier(variableName, resourceName, packageName);
} catch (Exception e) {
e.printStackTrace();
return -1;
}
}
}
列表:
public class Lists extends AppCompatActivity implements CategoriesFragment.OnHeadlineSelectedListener {
private String listName;
public void onItemSelected(String currentCategory) {
ItemsFragment itemsCallBackFragment = (ItemsFragment) getSupportFragmentManager().findFragmentById(R.id.itemsFragment);
if (itemsCallBackFragment != null) {
itemsCallBackFragment.updateArticleView(currentCategory);
} else {
ItemsFragment itemFragment = new ItemsFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.itemsFragment, itemFragment);
transaction.addToBackStack(null);
transaction.commit();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_triple_list);
setListsAdapter();
}
private void setListsAdapter() {
ViewPager tripleListViewPager = (ViewPager) findViewById(R.id.listsPager);
FragmentPagerAdapter tripleListFragmentAdapt = new ListsPagerAdapter(getSupportFragmentManager(), "LIST NAME", ApplicationUtils.getContext());
tripleListViewPager.setAdapter(tripleListFragmentAdapt);
}
}
ListsPagerAdapter:
public class ListsPagerAdapter extends FragmentPagerAdapter {
private static int NUM_TABS = 1;
private String listName;
private Context listsContext;
public ListsPagerAdapter(FragmentManager fm, String newListName, Context listsContext) {
super(fm);
setListName(newListName);
setListsContext(listsContext);
}
// Returns total number of pages
@Override
public int getCount() {
return NUM_TABS;
}
// Returns the fragment to display for that page
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return NewItemPagerFragment.newInstance();
default:
return null;
}
}
// Returns the page title for the top indicator
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return listsContext.getResources().getString(R.string.lists_tab_newItem, getListName());
default:
return "$value";
}
}
public String getListName() {
return listName;
}
public void setListName(String listName) {
this.listName = listName;
}
public Context getListsContext() {
return listsContext;
}
public void setListsContext(Context listsContext) {
this.listsContext = listsContext;
}
}
类别片段:
public class CategoriesFragment extends Fragment {
private List<Integer> categoryIds = new ArrayList<>();
private String currentCategory;
private View categoriesView;
OnHeadlineSelectedListener itemCallback;
public interface OnHeadlineSelectedListener {
void onItemSelected(String categoryName);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
try {
itemCallback = (OnHeadlineSelectedListener) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString()
+ " must implement OnHeadlineSelectedListener");
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
categoriesView = inflater.inflate(R.layout.fragment_categories, container, false);
categoriesView.setId(R.id.categoriesFragment);
return categoriesView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setCategoriesListener();
setDefaultSelectedCategory();
}
private void setCategoriesListener() {
categoryIds.add(R.id.category1);
for (Integer id : categoryIds) {
setListener(id);
}
}
private void setListener(final int categoryId) {
final ImageView categoryImg = (ImageView) categoriesView.findViewById(categoryId);
categoryImg.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
removePreviousSelectedCategory(categoryImg);
selectCategory(categoryId, categoryImg);
loadItemList();
}
});
}
private void removePreviousSelectedCategory(ImageView categoryImg) {
for (Integer id : categoryIds) {
final ImageView imgView = (ImageView) categoriesView.findViewById(id);
if (imgView.getTag() != null) {
String previousSelectedCategory = (String) imgView.getTag();
if (StringUtils.contains(previousSelectedCategory, Application.SELECTED)) {
previousSelectedCategory = previousSelectedCategory.replace(Application.SELECTED, "");
categoryImg.setTag(previousSelectedCategory);
Integer previousSelectedCategoryId = ApplicationUtils.getResourceId(previousSelectedCategory, Application.RES_DRAWABLE, ApplicationUtils.getJavaPackageName());
imgView.setImageResource(previousSelectedCategoryId);
}
}
}
}
private void selectCategory(int categoryId, ImageView categoryImg) {
String newSelectedCategory = ApplicationUtils.getResouceName(categoryId) + Application.SELECTED;
setCurrentCategory(newSelectedCategory);
newSelectedCategory = newSelectedCategory.replace(Application.META_INFO_ID, "");
categoryImg.setTag(newSelectedCategory);
Integer currentCategoryId = ApplicationUtils.getResourceId(newSelectedCategory, Application.RES_DRAWABLE, ApplicationUtils.getJavaPackageName());
categoryImg.setImageResource(currentCategoryId);
}
public String getCurrentCategory() {
return currentCategory;
}
public void setCurrentCategory(String currentCategory) {
this.currentCategory = currentCategory;
}
private void loadItemList() {
itemCallback.onItemSelected(getCurrentCategory());
}
private void setDefaultSelectedCategory() {
Integer categoryId = R.id.category1;
final ImageView categoryImg = (ImageView) categoriesView.findViewById(categoryId);
selectCategory(categoryId, categoryImg);
loadItemList();
}
}
项目片段:
public class ItemsFragment extends Fragment {
private View itemsFragmentView;
private ListView itemsListView;
private ItemAdapter itemsListAdapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
itemsFragmentView = inflater.inflate(R.layout.fragment_items, container, false);
itemsListView = (ListView) itemsFragmentView.findViewById(R.id.itemsListView);
setItemsListAdapter();
return itemsFragmentView;
}
public void updateArticleView(String categoryName) {
getSelectedCategoryList();
}
private void getSelectedCategoryList() {
List<String> testList = new ArrayList<>();
testList.add("TEST ITEM");
itemsListAdapter.update(testList);
}
private void setItemsListAdapter() {
itemsListAdapter = new ItemAdapter(getActivity(), R.layout.fragment_items, new ArrayList<String>());
itemsListView.setAdapter(itemsListAdapter);
}
}
物品适配器:
public class ItemAdapter extends ArrayAdapter<String> {
private List<String> items = new ArrayList<>();
private LayoutInflater rowInflater;
public ItemAdapter(Context context, int resource, List<String> itemsList) {
super(context, resource, itemsList);
this.items = itemsList;
this.rowInflater = LayoutInflater.from(context);
}
private class ItemHolder {
TextView itemNameView;
}
@Override
public View getView(int position, View rowView, ViewGroup parent) {
ItemHolder itemHolder;
if (rowView == null) {
rowView = rowInflater.inflate(R.layout.content_row_choose_item, parent, false);
itemHolder = new ItemHolder();
itemHolder.itemNameView = (TextView) rowView.findViewById(R.id.itemName);
rowView.setTag(itemHolder);
} else {
itemHolder = (ItemHolder) rowView.getTag();
}
String itemName = getItem(position);
if (StringUtils.isNotEmpty(itemName) && itemHolder.itemNameView != null) {
itemHolder.itemNameView.setText(itemName);
System.out.println("ITEM NAME ### " + itemHolder.itemNameView.getText());
}
return rowView;
}
public void update(List<String> items) {
this.items.clear();
this.items.addAll(items);
this.notifyDataSetChanged();
}
public List<String> getItems() {
return items;
}
}
随机刺...
如果使用 ListFragment
,则 fragment_items.xml
需要 ListView
和 android:id="@android:id/list"
。
您甚至试图加载具有该 ID 的 ListView。
itemsFragmentView = inflater.inflate(R.layout.fragment_items, container, false);
itemsListView = (ListView) itemsFragmentView.findViewById(android.R.id.list);
但是,你有android:id="@+id/itemsListView"
fragment_items:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@id/itemsFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ListView
android:id="@+id/itemsListView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:divider="@null" />
</LinearLayout>
如果使用 ListFragment,则无需实现自己的 XML 布局文件。也就是说,onCreateView
不需要实施。请改用 onActivityCreated
。
@Override
public void onActivityCreated(Bundle savedInstanceState) {
itemsListView = getListView();
itemsListAdapter = new ItemAdapter(getActivity());
setListAdapter(itemsListAdapter);
super.onActivityCreated(savedInstanceState);
}
现在,如果您想向适配器添加项目,我通常建议您只使用 ArrayAdapter<String>
。这将为您提供一个 add(String object)
方法,该方法将添加到基础列表并通知更新。
关于getView
的问题,真的不好说。我真的不知道你为什么需要 ItemAdapter
,因为默认的 ArrayAdapter<String>
会起作用,假设你给它传递一个带有 android:id="@android:id/text1
的布局,例如使用 android.R.layout.simple_list_item_1
代替 R.layout.content_row_choose_item
所以,这看起来像。
@Override
public void onActivityCreated(Bundle savedInstanceState) {
itemsListView = getListView();
ArrayAdapter<String> itemsListAdapter = new ArrayAdapter<String>(
getActivity(), android.R.layout.simple_list_item_1);
setListAdapter(itemsListAdapter);
adapter.add("Hello");
adapter.add("World");
super.onActivityCreated(savedInstanceState);
}
给定的 MCVE 工作正常。经过 7 天的调试和取消注释代码,我找到了问题的答案。
我的列表已正确更新,但未呈现,因为第二个 ItemsFragemnt
在 Lists
Activity 加载时被初始化。第二个片段覆盖了第一个片段,这就是为什么我没有看到我的列表是 displayed/refreshed.
列表:
第一个创建的片段:
private void setListsAdapter() {
ViewPager tripleListViewPager = (ViewPager) findViewById(R.id.listsPager);
FragmentPagerAdapter tripleListFragmentAdapt = new ListsPagerAdapter(getSupportFragmentManager(), "LIST NAME", ApplicationUtils.getContext());
tripleListViewPager.setAdapter(tripleListFragmentAdapt); }
在 ListsPagerAdapter
中有一个调用,用 CategoriesFragment
和 ItemsFragment
.
填充我的 ViewPager
(NewItemPagerFragment
)
第二个创建的片段 - 叠加层:
ItemsFragment itemFragment = new ItemsFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.itemsFragment, itemFragment);
transaction.addToBackStack(null);
transaction.commit();
我试图断点我的代码,之前在事实中提到过问题范围,但有时这真的很痛苦。我想到了使用 Log.d(TAG_KEY, TAG_NAME);
的想法,那时我找到了答案:我意识到 ItemsFragment
在 Activity 负载上被调用了两次。
我在我的项目中搜索 new ItemsFragment
并看到在我的 NewItemPagerFragment
onCreate
中,正在调用 ItemsFragment
。同样在 CategoriesFragment
之前-就像这样:
NewItemPagerFragment:
Fragment itemsFragment = new ItemsFragment();
FragmentManager fm1 = getChildFragmentManager();
FragmentTransaction ft1 = fm1.beginTransaction();
ft1.replace(R.id.itemsFragment, itemsFragment);
ft1.commit();
Fragment categoriesFragment = new CategoriesFragment();
FragmentManager fm = getChildFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.categoriesFragment, categoriesFragment);
ft.commit();
这解释了 事实 2.。在 commenting/remove 对 NewItemPagerFragment
的调用之后,问题就消失了。
底线是: 确保你的列表是正确的 fulfilled/updated 像 notifyDataSetChanged
这样的cricket_007 在他的回答和我在互联网上阅读的其他数千篇文章中提到。同样,请确保您没有覆盖调用其初始化两次的片段。
Objective: 我有一个 activity 并且在两个片段中。 ideia是将两个fragments进行通信,选择一个category并更新其item list.On activity load,一个category是默认settle的。
问题: 在 activity 加载时,ItemsFragment 没有 display/update itemsLisView。 ItemAdapter 的 getView 方法也只被调用了两次,即使列表有五个项目。
事实:
- 项目列表在传递给适配器之前已正确完成
- 断点代码,不确定为什么或是否重要,ItemsFragment rendered/called 在 CategoriesFragments 之前。我发现这很奇怪,因为 CategoriesFragments 位于 ItemsFragment 之上。这就是我写
if (getArguments() != null)
的原因。在我得到空指针异常之前。
研究:关于这两个主题有很多问题。
- Android ListView not refreshing after notifyDataSetChanged with data as Map
- ListFragment Not Rendering and getView() in Adapter Not Being Called
- Android getView() not being called properly?
- BaseAdapter notifyDatasetChanged() called but getView() is never called
这些是我经历过的一些 link 个例子(数以千计),试图为我的案例找到解决方案。不幸的是 none 他们成功了。
我已经被这个问题困扰将近 5 天了,我想我在这里遗漏了一些 Android 概念。这与 Java 编程无关,至少我希望如此。
问题:
- 为什么 ItemsFragment 在 activity 加载时不显示项目列表? (这可能解决了更新问题)
- 为什么 ItemAdapter 只调用 getView 两次,即使 Items List 正确地给他更多的项目?
如需任何进一步的信息,请不要介意询问。 在此先感谢您的帮助。
编辑 - MCVE:
activity_triple_list:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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:fitsSystemWindows="true"
tools:context=".controller.activities.Lists">
<include layout="@layout/content_triple_list" />
</android.support.design.widget.CoordinatorLayout>
content_triple_list:
<?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.support.v4.view.ViewPager
android:id="@+id/listsPager"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.PagerTabStrip
android:id="@+id/pager_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:paddingBottom="4dp"
android:paddingTop="4dp" />
</android.support.v4.view.ViewPager>
</LinearLayout>
fragment_categories:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/categoriesFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TableLayout
android:id="@+id/categoriesTable"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:stretchColumns="4">
<TableRow
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_marginTop="5dp"
android:gravity="center_horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="0"
android:layout_marginLeft="13dp"
android:layout_marginRight="13dp"
android:orientation="vertical">
<TextView
android:id="@+id/category1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="CATEGORY 1"
android:textAlignment="center"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
</TableRow>
</TableLayout>
</LinearLayout>
fragment_items:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@id/itemsFragment"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<ListView
android:id="@+id/itemsListView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:divider="@null" />
</LinearLayout>
content_row_choose_item:
<?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:background="@drawable/custom_row"
android:orientation="vertical"
android:paddingBottom="5dp"
android:paddingLeft="15dp"
android:paddingTop="5dp">
<TextView
android:id="@+id/itemName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TEST"
android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>
custom_row:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:background="#2fff00">
<item android:drawable="@color/colorPrimary" android:state_pressed="true" /> <!-- pressed -->
</selector>
ApplicationUtils:
public final class ApplicationUtils extends Application {
private static Context context;
public void onCreate() {
super.onCreate();
ApplicationUtils.context = getApplicationContext();
}
public static Context getContext() {
return ApplicationUtils.context;
}
public static String getJavaPackageName() {
return ApplicationUtils.context.getPackageName();
}
public static Resources getAppResources() {
return getContext().getResources();
}
public static String getResouceName(Integer id) {
return getAppResources().getResourceName(id);
}
public static String getResourceString(Integer id) {
return getAppResources().getString(id);
}
public static int getResourceId(String variableName, String resourceName, String packageName) {
try {
return getContext().getResources().getIdentifier(variableName, resourceName, packageName);
} catch (Exception e) {
e.printStackTrace();
return -1;
}
}
}
列表:
public class Lists extends AppCompatActivity implements CategoriesFragment.OnHeadlineSelectedListener {
private String listName;
public void onItemSelected(String currentCategory) {
ItemsFragment itemsCallBackFragment = (ItemsFragment) getSupportFragmentManager().findFragmentById(R.id.itemsFragment);
if (itemsCallBackFragment != null) {
itemsCallBackFragment.updateArticleView(currentCategory);
} else {
ItemsFragment itemFragment = new ItemsFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.itemsFragment, itemFragment);
transaction.addToBackStack(null);
transaction.commit();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_triple_list);
setListsAdapter();
}
private void setListsAdapter() {
ViewPager tripleListViewPager = (ViewPager) findViewById(R.id.listsPager);
FragmentPagerAdapter tripleListFragmentAdapt = new ListsPagerAdapter(getSupportFragmentManager(), "LIST NAME", ApplicationUtils.getContext());
tripleListViewPager.setAdapter(tripleListFragmentAdapt);
}
}
ListsPagerAdapter:
public class ListsPagerAdapter extends FragmentPagerAdapter {
private static int NUM_TABS = 1;
private String listName;
private Context listsContext;
public ListsPagerAdapter(FragmentManager fm, String newListName, Context listsContext) {
super(fm);
setListName(newListName);
setListsContext(listsContext);
}
// Returns total number of pages
@Override
public int getCount() {
return NUM_TABS;
}
// Returns the fragment to display for that page
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return NewItemPagerFragment.newInstance();
default:
return null;
}
}
// Returns the page title for the top indicator
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return listsContext.getResources().getString(R.string.lists_tab_newItem, getListName());
default:
return "$value";
}
}
public String getListName() {
return listName;
}
public void setListName(String listName) {
this.listName = listName;
}
public Context getListsContext() {
return listsContext;
}
public void setListsContext(Context listsContext) {
this.listsContext = listsContext;
}
}
类别片段:
public class CategoriesFragment extends Fragment {
private List<Integer> categoryIds = new ArrayList<>();
private String currentCategory;
private View categoriesView;
OnHeadlineSelectedListener itemCallback;
public interface OnHeadlineSelectedListener {
void onItemSelected(String categoryName);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
try {
itemCallback = (OnHeadlineSelectedListener) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString()
+ " must implement OnHeadlineSelectedListener");
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
categoriesView = inflater.inflate(R.layout.fragment_categories, container, false);
categoriesView.setId(R.id.categoriesFragment);
return categoriesView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setCategoriesListener();
setDefaultSelectedCategory();
}
private void setCategoriesListener() {
categoryIds.add(R.id.category1);
for (Integer id : categoryIds) {
setListener(id);
}
}
private void setListener(final int categoryId) {
final ImageView categoryImg = (ImageView) categoriesView.findViewById(categoryId);
categoryImg.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
removePreviousSelectedCategory(categoryImg);
selectCategory(categoryId, categoryImg);
loadItemList();
}
});
}
private void removePreviousSelectedCategory(ImageView categoryImg) {
for (Integer id : categoryIds) {
final ImageView imgView = (ImageView) categoriesView.findViewById(id);
if (imgView.getTag() != null) {
String previousSelectedCategory = (String) imgView.getTag();
if (StringUtils.contains(previousSelectedCategory, Application.SELECTED)) {
previousSelectedCategory = previousSelectedCategory.replace(Application.SELECTED, "");
categoryImg.setTag(previousSelectedCategory);
Integer previousSelectedCategoryId = ApplicationUtils.getResourceId(previousSelectedCategory, Application.RES_DRAWABLE, ApplicationUtils.getJavaPackageName());
imgView.setImageResource(previousSelectedCategoryId);
}
}
}
}
private void selectCategory(int categoryId, ImageView categoryImg) {
String newSelectedCategory = ApplicationUtils.getResouceName(categoryId) + Application.SELECTED;
setCurrentCategory(newSelectedCategory);
newSelectedCategory = newSelectedCategory.replace(Application.META_INFO_ID, "");
categoryImg.setTag(newSelectedCategory);
Integer currentCategoryId = ApplicationUtils.getResourceId(newSelectedCategory, Application.RES_DRAWABLE, ApplicationUtils.getJavaPackageName());
categoryImg.setImageResource(currentCategoryId);
}
public String getCurrentCategory() {
return currentCategory;
}
public void setCurrentCategory(String currentCategory) {
this.currentCategory = currentCategory;
}
private void loadItemList() {
itemCallback.onItemSelected(getCurrentCategory());
}
private void setDefaultSelectedCategory() {
Integer categoryId = R.id.category1;
final ImageView categoryImg = (ImageView) categoriesView.findViewById(categoryId);
selectCategory(categoryId, categoryImg);
loadItemList();
}
}
项目片段:
public class ItemsFragment extends Fragment {
private View itemsFragmentView;
private ListView itemsListView;
private ItemAdapter itemsListAdapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
itemsFragmentView = inflater.inflate(R.layout.fragment_items, container, false);
itemsListView = (ListView) itemsFragmentView.findViewById(R.id.itemsListView);
setItemsListAdapter();
return itemsFragmentView;
}
public void updateArticleView(String categoryName) {
getSelectedCategoryList();
}
private void getSelectedCategoryList() {
List<String> testList = new ArrayList<>();
testList.add("TEST ITEM");
itemsListAdapter.update(testList);
}
private void setItemsListAdapter() {
itemsListAdapter = new ItemAdapter(getActivity(), R.layout.fragment_items, new ArrayList<String>());
itemsListView.setAdapter(itemsListAdapter);
}
}
物品适配器:
public class ItemAdapter extends ArrayAdapter<String> {
private List<String> items = new ArrayList<>();
private LayoutInflater rowInflater;
public ItemAdapter(Context context, int resource, List<String> itemsList) {
super(context, resource, itemsList);
this.items = itemsList;
this.rowInflater = LayoutInflater.from(context);
}
private class ItemHolder {
TextView itemNameView;
}
@Override
public View getView(int position, View rowView, ViewGroup parent) {
ItemHolder itemHolder;
if (rowView == null) {
rowView = rowInflater.inflate(R.layout.content_row_choose_item, parent, false);
itemHolder = new ItemHolder();
itemHolder.itemNameView = (TextView) rowView.findViewById(R.id.itemName);
rowView.setTag(itemHolder);
} else {
itemHolder = (ItemHolder) rowView.getTag();
}
String itemName = getItem(position);
if (StringUtils.isNotEmpty(itemName) && itemHolder.itemNameView != null) {
itemHolder.itemNameView.setText(itemName);
System.out.println("ITEM NAME ### " + itemHolder.itemNameView.getText());
}
return rowView;
}
public void update(List<String> items) {
this.items.clear();
this.items.addAll(items);
this.notifyDataSetChanged();
}
public List<String> getItems() {
return items;
}
}
随机刺...
如果使用 ListFragment
,则 fragment_items.xml
需要 ListView
和 android:id="@android:id/list"
。
您甚至试图加载具有该 ID 的 ListView。
itemsFragmentView = inflater.inflate(R.layout.fragment_items, container, false);
itemsListView = (ListView) itemsFragmentView.findViewById(android.R.id.list);
但是,你有android:id="@+id/itemsListView"
fragment_items:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@id/itemsFragment" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ListView android:id="@+id/itemsListView" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:divider="@null" /> </LinearLayout>
如果使用 ListFragment,则无需实现自己的 XML 布局文件。也就是说,onCreateView
不需要实施。请改用 onActivityCreated
。
@Override
public void onActivityCreated(Bundle savedInstanceState) {
itemsListView = getListView();
itemsListAdapter = new ItemAdapter(getActivity());
setListAdapter(itemsListAdapter);
super.onActivityCreated(savedInstanceState);
}
现在,如果您想向适配器添加项目,我通常建议您只使用 ArrayAdapter<String>
。这将为您提供一个 add(String object)
方法,该方法将添加到基础列表并通知更新。
关于getView
的问题,真的不好说。我真的不知道你为什么需要 ItemAdapter
,因为默认的 ArrayAdapter<String>
会起作用,假设你给它传递一个带有 android:id="@android:id/text1
的布局,例如使用 android.R.layout.simple_list_item_1
代替 R.layout.content_row_choose_item
所以,这看起来像。
@Override
public void onActivityCreated(Bundle savedInstanceState) {
itemsListView = getListView();
ArrayAdapter<String> itemsListAdapter = new ArrayAdapter<String>(
getActivity(), android.R.layout.simple_list_item_1);
setListAdapter(itemsListAdapter);
adapter.add("Hello");
adapter.add("World");
super.onActivityCreated(savedInstanceState);
}
给定的 MCVE 工作正常。经过 7 天的调试和取消注释代码,我找到了问题的答案。
我的列表已正确更新,但未呈现,因为第二个 ItemsFragemnt
在 Lists
Activity 加载时被初始化。第二个片段覆盖了第一个片段,这就是为什么我没有看到我的列表是 displayed/refreshed.
列表:
第一个创建的片段:
private void setListsAdapter() {
ViewPager tripleListViewPager = (ViewPager) findViewById(R.id.listsPager);
FragmentPagerAdapter tripleListFragmentAdapt = new ListsPagerAdapter(getSupportFragmentManager(), "LIST NAME", ApplicationUtils.getContext());
tripleListViewPager.setAdapter(tripleListFragmentAdapt); }
在 ListsPagerAdapter
中有一个调用,用 CategoriesFragment
和 ItemsFragment
.
ViewPager
(NewItemPagerFragment
)
第二个创建的片段 - 叠加层:
ItemsFragment itemFragment = new ItemsFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.itemsFragment, itemFragment);
transaction.addToBackStack(null);
transaction.commit();
我试图断点我的代码,之前在事实中提到过问题范围,但有时这真的很痛苦。我想到了使用 Log.d(TAG_KEY, TAG_NAME);
的想法,那时我找到了答案:我意识到 ItemsFragment
在 Activity 负载上被调用了两次。
我在我的项目中搜索 new ItemsFragment
并看到在我的 NewItemPagerFragment
onCreate
中,正在调用 ItemsFragment
。同样在 CategoriesFragment
之前-就像这样:
NewItemPagerFragment:
Fragment itemsFragment = new ItemsFragment();
FragmentManager fm1 = getChildFragmentManager();
FragmentTransaction ft1 = fm1.beginTransaction();
ft1.replace(R.id.itemsFragment, itemsFragment);
ft1.commit();
Fragment categoriesFragment = new CategoriesFragment();
FragmentManager fm = getChildFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.categoriesFragment, categoriesFragment);
ft.commit();
这解释了 事实 2.。在 commenting/remove 对 NewItemPagerFragment
的调用之后,问题就消失了。
底线是: 确保你的列表是正确的 fulfilled/updated 像 notifyDataSetChanged
这样的cricket_007 在他的回答和我在互联网上阅读的其他数千篇文章中提到。同样,请确保您没有覆盖调用其初始化两次的片段。