列表项单击时 ListFragment 不会替换 ListFragment
Posted
技术标签:
【中文标题】列表项单击时 ListFragment 不会替换 ListFragment【英文标题】:ListFragment won't replace ListFragment when list item click 【发布时间】:2017-07-23 20:47:03 【问题描述】:我正在开发一个具有显示 ListFragment 的 FragmentPagerAdapter 的应用程序。如果用户单击列表中的某个项目,我将尝试执行 FragmentTransaction 并将当前 Fragment 替换为下一个。
但是,当我尝试在 onItemClick 中切换片段时,没有任何反应,没有错误,但列表片段没有改变。我附上了我目前正在尝试的相关代码。我认为这是因为我使用了错误的 fragmentManager,但我不确定如何获得正确的。
一个 FragmentPagerAdapter,它返回一个对应于应用程序主要部分之一的片段。
public static class AppSectionsPagerAdapter extends FragmentPagerAdapter
public AppSectionsPagerAdapter(FragmentManager fm)
super(fm);
@Override
public Fragment getItem(int i)
switch (i)
case 0:
// The first section of the app is the most interesting -- it offers
// a launchpad into the other demonstrations in this example application.
return new LaunchpadSectionFragment();
case 1:
return new LibrarySectionFragment();
case 2:
return new LipshapeSectionFragment();
default:
// The other sections of the app are dummy placeholders.
Fragment fragment = new DummySectionFragment();
Bundle args = new Bundle();
args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, i + 1);
fragment.setArguments(args);
return fragment;
@Override
public int getCount()
return 3;
@Override
public CharSequence getPageTitle(int position)
switch (position)
case 0:
return "Practice";
case 1:
return "Library";
case 2:
return "Help";
return "Untitled";
这是具有 onClick 的 ListFragment
public static class LipshapeSectionFragment extends ListFragment implements AdapterView.OnItemClickListener
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
View rootView = inflater.inflate(R.layout.fragment_section_library, container, false);
return rootView;
@Override
public void onActivityCreated(Bundle savedInstanceState)
super.onActivityCreated(savedInstanceState);
ContentResolver resolver = this.getContext().getContentResolver();
// if you only want one column do it like this
// String[] projection = new String[]BaseColumns._ID, VideoFilesContract.videoFiles.FILENAME;
Cursor lipshapeCursor =
resolver.query(LipshapeContract.lipshapes.CONTENT_URI,
LipshapeContract.lipshapes.PROJECTION_ALL,
null,
null,
null);
lipshapeCursor.moveToFirst();
// Setup cursor adapter using cursor from last step
LipshapeCursorAdapter lipshapeAdapter = new LipshapeCursorAdapter(this.getContext(), lipshapeCursor);
// Attach cursor adapter to the ListView
setListAdapter(lipshapeAdapter);
getListView().setOnItemClickListener(this);
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,long id)
Cursor cursor = ((Cursor) getListView().getItemAtPosition(position));
ContentResolver resolver = this.getContext().getContentResolver();
Cursor wordCursor =
resolver.query(WordContract.wordItems.CONTENT_URI,
WordContract.wordItems.PROJECTION_ALL,
"lipshape_id=?",
new String[]cursor.getString(cursor.getColumnIndex("_id")),
null);
int count = wordCursor.getCount();
TestSectionFragment fragment = new TestSectionFragment();
FragmentManager fragmentManager = getChildFragmentManager();
fragmentManager.beginTransaction().replace(R.id.lvLibrary, fragment).addToBackStack(null).commit();
//Toast.makeText(getActivity(), "Words within this group: " + count, Toast.LENGTH_SHORT).show();
ListFragment 的布局文件(fragment_section_library):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/lvLibrary"
android:layout_
android:layout_>
<ListView
android:id="@android:id/list"
android:layout_
android:layout_ />
</LinearLayout>
我正在尝试将 ListFragment 替换为的测试片段:
*/
public static class TestSectionFragment extends Fragment
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
View rootView = inflater.inflate(R.layout.fragment_section_dummy, container, false);
Bundle args = getArguments();
((TextView) rootView.findViewById(android.R.id.text1)).setText(
"Test Worked");
return rootView;
TestFragment 的布局文件(fragment_section_dummy):
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
android:layout_
android:layout_
android:gravity="center"
android:textSize="24sp"
android:padding="32dp" />
【问题讨论】:
【参考方案1】:我已经设法找到了问题所在。主要问题是您必须先以编程方式添加片段,然后才能替换它,这是解决问题所需的更改,它显示了一个列表视图,该列表视图在 listItem 单击时被另一个列表视图替换:
/**
* A lipshape list fragment
*/
public static class LipshapeSectionFragment extends ListFragment implements AdapterView.OnItemClickListener, LoaderManager.LoaderCallbacks<Cursor>
public LipshapeCursorAdapter lipshapeAdapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
View rootView = inflater.inflate(R.layout.fragment_section_library, container, false);
return rootView;
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
ContentResolver resolver = this.getContext().getContentResolver();
// if you only want one column do it like this
// String[] projection = new String[]BaseColumns._ID, VideoFilesContract.videoFiles.FILENAME;
Cursor lipshapeCursor =
resolver.query(LipshapeContract.lipshapes.CONTENT_URI,
LipshapeContract.lipshapes.PROJECTION_ALL,
null,
null,
null);
// Setup cursor adapter using cursor from last step
lipshapeAdapter = new LipshapeCursorAdapter(this.getContext(), lipshapeCursor);
// Attach cursor adapter to the ListView
//setListAdapter(lipshapeAdapter);
//getListView().setOnItemClickListener(this);
@Override
public void onActivityCreated(Bundle savedInstanceState)
super.onActivityCreated(savedInstanceState);
@Override
public void onViewCreated(View view, Bundle savedInstanceState)
super.onViewCreated(view, savedInstanceState);
setListAdapter(lipshapeAdapter);
getListView().setOnItemClickListener(this);
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,long id)
Cursor cursor = ((Cursor) getListView().getItemAtPosition(position));
ContentResolver resolver = this.getContext().getContentResolver();
Cursor wordCursor =
resolver.query(WordContract.wordItems.CONTENT_URI,
WordContract.wordItems.PROJECTION_ALL,
"lipshape_id=?",
new String[]cursor.getString(cursor.getColumnIndex("_id")),
null);
int count = wordCursor.getCount();
WordListSectionFragment fragment = new WordListSectionFragment();
Bundle args = new Bundle();
args.putString("lipshape_selected", cursor.getString(cursor.getColumnIndex("_id")));
fragment.setArguments(args);
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.svBody, fragment).addToBackStack(null).commit();
//Toast.makeText(getActivity(), "Words within this group: " + count, Toast.LENGTH_SHORT).show();
@Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle)
return null;
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor)
@Override
public void onLoaderReset(Loader<Cursor> loader)
单词列表片段
/**
*
* WordListFragment
*/
public static class WordListSectionFragment extends ListFragment implements AdapterView.OnItemClickListener, LoaderManager.LoaderCallbacks<Cursor>
public static final String ARG_SECTION_NUMBER = "section_number";
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
View rootView = inflater.inflate(R.layout.fragment_section_wordlist, container, false);
return rootView;
@Override
public void onActivityCreated(Bundle savedInstanceState)
super.onActivityCreated(savedInstanceState);
ContentResolver resolver = getContext().getContentResolver();
Bundle args = getArguments();
Cursor wordCursor =
resolver.query(WordContract.wordItems.CONTENT_URI,
WordContract.wordItems.PROJECTION_ALL,
"lipshape_id=?",
new String[]args.getString("lipshape_selected"),
null);
wordCursor.moveToFirst();
// Setup cursor adapter using cursor from last step
WordCursorAdapter wordAdapter = new WordCursorAdapter(this.getContext(), wordCursor);
// Attach cursor adapter to the ListView
setListAdapter(wordAdapter);
getListView().setOnItemClickListener(this);
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position,long id)
Cursor cursor = ((Cursor) getListView().getItemAtPosition(position));
String test = cursor.getString(cursor.getColumnIndex("description"));
int word_id = cursor.getInt(cursor.getColumnIndex("_id"));
Intent intent = new Intent(getActivity(), CollectionDemoActivity.class);
intent.putExtra("word_id", word_id);
startActivity(intent);
@Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle)
return null;
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor)
@Override
public void onLoaderReset(Loader<Cursor> loader)
LibrarySectionFragment
/**
*
* A library fragment
*/
public static class LibrarySectionFragment extends Fragment
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState)
LipshapeSectionFragment fragment = new LipshapeSectionFragment();
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().add(R.id.svBody, fragment).commit();
super.onActivityCreated(savedInstanceState);
@Override
public void onCreate(@Nullable Bundle savedInstanceState)
super.onCreate(savedInstanceState);
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
View rootView = inflater.inflate(R.layout.fragment_section_dummy, container, false);
Bundle args = getArguments();
return rootView;
主要变化来自第一个列表片段:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/lvLibrary"
android:layout_
android:layout_>
<ListView
android:id="@android:id/list"
android:layout_
android:layout_ />
</LinearLayout>
接下来我们有它所在的基础片段:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/svBody"
android:layout_
android:layout_
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin">
</LinearLayout>
【讨论】:
以上是关于列表项单击时 ListFragment 不会替换 ListFragment的主要内容,如果未能解决你的问题,请参考以下文章
ListFragment OnListItemClick 未被调用
OnItemLongClickListener() 不会导致 ListFragment 中的日志点击手势