ViewPager 不显示第一个片段,如果它的内容是动态加载的
ViewPager doesn't show first fragment, if its contents are loaded dynamically
我在 android 应用程序中构建带有片段的 viewPager 时遇到了一个非常奇怪的问题。我有一个 activity,用于构建布局和两个片段:每个片段都包含 RecyclerView 并从服务器动态加载其内容。当我用片段的静态内容测试它时,一切都很好,但是当我切换到预先测试和工作的动态内容片段时,ViewPager 从不加载第一个,只加载第二个。如果我交换它们,viewPager 仍然只加载第二个。在第一个选项卡中,我总是只看到一个白色的空白字段。
任何帮助将不胜感激。
activity部分:
tabLayout = (TabLayout) findViewById(R.id.contacts_tabs_layout);
adapter = new ContactsPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(adapter);
tabLayout.setupWithViewPager(viewPager);
activity布局:
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar_parent"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" />
<android.support.design.widget.TabLayout
android:id="@+id/contacts_tabs_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMaxWidth="0dp"
app:tabGravity="fill"
app:tabMode="scrollable">
</android.support.design.widget.TabLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/view_pager_contacts_list"
android:layout_width="match_parent"
android:layout_height="fill_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
片段布局:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/contacts_list"
android:layout_width="fill_parent"
android:layout_height="match_parent" />
片段相关代码:
contactsList = (RecyclerView) v.findViewById(R.id.contacts_list);
contactsList.setLayoutManager(new LinearLayoutManager(getActivity()));
adapter = new ContactsListAdapter(getActivity());
contactsList.setAdapter(adapter);
controller.getContacts(new CommunicationListener() {
@Override
public void onFileReceived(FilePath filePath, byte[] data) {
System.out.println("RECEIVED CONTACTS DATA FILE WITH SIZE OF " + data.length);
final Contact c = Utils.deserializeContact(data);
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
adapter.add(c);
}
});
}
});
return v;
适配器部分:
public ContactsPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
@Override
public Fragment getItem(int position)
{
switch(position){
case 0:
return new ContactsListFragment();
case 1:
return new TestFragment();
default:
return null;
}
}
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
@Override
public int getCount() {
return 2;
}
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
来自 PagerAdapter
的 javadoc POSITION_NONE
意味着该项目不再存在。
/**
* Called when the host view is attempting to determine if an item's position
* has changed. Returns {@link #POSITION_UNCHANGED} if the position of the given
* item has not changed or {@link #POSITION_NONE} if the item is no longer present
* in the adapter.
*
*
The default implementation assumes that items will never
* change position and always returns {@link #POSITION_UNCHANGED}.
*
* @param object Object representing an item, previously returned by a call to
* {@link #instantiateItem(View, int)}.
* @return object's new position index from [0, {@link #getCount()}),
* {@link #POSITION_UNCHANGED} if the object's position has not changed,
* or {@link #POSITION_NONE} if the item is no longer present.
*/
您应该 return 项目的位置或 POSITION_UNCHANGED
。
另外:
`PagerAdapter` supports data set changes. Data set changes must occur
on the * `main thread` and must end with a call to {@link #notifyDataSetChanged()} similar * to AdapterView adapters derived from {@link android.widget.BaseAdapter}. A data * set change may
involve pages being added, removed, or changing position. The *
ViewPager will keep the current page active provided the adapter
implements * the method {@link #getItemPosition(Object)}.
添加片段后需要调用notifyDatasetChanged()
。
我在 android 应用程序中构建带有片段的 viewPager 时遇到了一个非常奇怪的问题。我有一个 activity,用于构建布局和两个片段:每个片段都包含 RecyclerView 并从服务器动态加载其内容。当我用片段的静态内容测试它时,一切都很好,但是当我切换到预先测试和工作的动态内容片段时,ViewPager 从不加载第一个,只加载第二个。如果我交换它们,viewPager 仍然只加载第二个。在第一个选项卡中,我总是只看到一个白色的空白字段。 任何帮助将不胜感激。
activity部分:
tabLayout = (TabLayout) findViewById(R.id.contacts_tabs_layout);
adapter = new ContactsPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(adapter);
tabLayout.setupWithViewPager(viewPager);
activity布局:
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar_parent"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" />
<android.support.design.widget.TabLayout
android:id="@+id/contacts_tabs_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMaxWidth="0dp"
app:tabGravity="fill"
app:tabMode="scrollable">
</android.support.design.widget.TabLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/view_pager_contacts_list"
android:layout_width="match_parent"
android:layout_height="fill_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
片段布局:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/contacts_list"
android:layout_width="fill_parent"
android:layout_height="match_parent" />
片段相关代码:
contactsList = (RecyclerView) v.findViewById(R.id.contacts_list);
contactsList.setLayoutManager(new LinearLayoutManager(getActivity()));
adapter = new ContactsListAdapter(getActivity());
contactsList.setAdapter(adapter);
controller.getContacts(new CommunicationListener() {
@Override
public void onFileReceived(FilePath filePath, byte[] data) {
System.out.println("RECEIVED CONTACTS DATA FILE WITH SIZE OF " + data.length);
final Contact c = Utils.deserializeContact(data);
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
adapter.add(c);
}
});
}
});
return v;
适配器部分:
public ContactsPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
}
@Override
public Fragment getItem(int position)
{
switch(position){
case 0:
return new ContactsListFragment();
case 1:
return new TestFragment();
default:
return null;
}
}
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
@Override
public int getCount() {
return 2;
}
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
来自 PagerAdapter
的 javadoc POSITION_NONE
意味着该项目不再存在。
/** * Called when the host view is attempting to determine if an item's position * has changed. Returns {@link #POSITION_UNCHANGED} if the position of the given * item has not changed or {@link #POSITION_NONE} if the item is no longer present * in the adapter. * *
The default implementation assumes that items will never * change position and always returns {@link #POSITION_UNCHANGED}. * * @param object Object representing an item, previously returned by a call to * {@link #instantiateItem(View, int)}. * @return object's new position index from [0, {@link #getCount()}), * {@link #POSITION_UNCHANGED} if the object's position has not changed, * or {@link #POSITION_NONE} if the item is no longer present. */
您应该 return 项目的位置或 POSITION_UNCHANGED
。
另外:
`PagerAdapter` supports data set changes. Data set changes must occur on the * `main thread` and must end with a call to {@link #notifyDataSetChanged()} similar * to AdapterView adapters derived from {@link android.widget.BaseAdapter}. A data * set change may involve pages being added, removed, or changing position. The * ViewPager will keep the current page active provided the adapter implements * the method {@link #getItemPosition(Object)}.
添加片段后需要调用notifyDatasetChanged()
。