dea*_*ish 7 android android-tablayout
我有一个示例项目TabLayout和PagerAdapter.奇怪的事情发生了TabLayout当我打电话pagerAdapter.notifyDataSetChanged();后,tabLayout.setupWithViewPager(viewPager);
TabLayout滚动到未知的x位置,因此当前选项卡不可见.但是,如果我向左滚动到期望选项卡,则此选项卡有指示符.
到底是怎么回事?谁能帮助我?我花了太多时间.
代码下方.
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Get the ViewPager and set it's PagerAdapter so that it can display items
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
final SampleFragmentPagerAdapter pagerAdapter = new SampleFragmentPagerAdapter(getSupportFragmentManager(), MainActivity.this);
viewPager.setAdapter(pagerAdapter);
// Give the TabLayout the ViewPager
TabLayout tabLayout = (TabLayout) findViewById(R.id.sliding_tabs);
tabLayout.setupWithViewPager(viewPager);
findViewById(R.id.fab).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
pagerAdapter.notifyDataSetChanged();
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
我测试了nexus仿真器和nexus真实设备(api 21+)
Gradle设置:
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "xx.xxx.myapplication4"
minSdkVersion 21
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
Run Code Online (Sandbox Code Playgroud)
链接到报告的问题并准备在此处测试项目作为附件
每次使用设置视图寻呼机setupWithViewPager可能都是昂贵的.因为notifyDataSetChanged()在ViewPager适配器上导致TabLayout重绘其所有视图.因此,对于重绘,TabLayout删除所有关联的Views并重新添加它们.
请检查以下notifyDataSetChanged在寻呼机适配器之后发生的线程执行步骤.
at android.support.design.widget.TabLayout.removeAllTabs(TabLayout.java:654)
at android.support.design.widget.TabLayout.populateFromPagerAdapter(TabLayout.java:904)
at android.support.design.widget.TabLayout$PagerAdapterObserver.onChanged(TabLayout.java:2211)
at android.database.DataSetObservable.notifyChanged(DataSetObservable.java:37)
- locked <0x129f> (a java.util.ArrayList)
at android.support.v4.view.PagerAdapter.notifyDataSetChanged(PagerAdapter.java:287)
at com.sample.testtablayout.MainActivity$1.onClick(MainActivity.java:45)
Run Code Online (Sandbox Code Playgroud)
根据线程执行 -
单击操作按钮>寻呼机适配器通知已更改数据集> TabLayout通过观察者获得数据更改通知>它尝试从适配器填充新数据>删除所有选项卡.
下面是一个TabLayout类代码,您可以从中检查所有选项卡何时删除,然后最后选择的选项卡丢失(故意标记为空).
/**
* Remove all tabs from the action bar and deselect the current tab.
*/
public void removeAllTabs() {
// Remove all the views
for (int i = mTabStrip.getChildCount() - 1; i >= 0; i--) {
removeTabViewAt(i);
}
for (final Iterator<Tab> i = mTabs.iterator(); i.hasNext();) {
final Tab tab = i.next();
i.remove();
tab.reset();
sTabPool.release(tab);
}
mSelectedTab = null; // Thats a cause for your issue.
}
Run Code Online (Sandbox Code Playgroud)
为了保留最后选择的选项卡,我创建了自己的CustomTabLayout类并保留了最后选择的位置.
public class RetainableTabLayout extends TabLayout {
/*
* Variable to store invalid position.
*/
private static final int INVALID_TAB_POS = -1;
/*
* Variable to store last selected position, init it with invalid tab position.
*/
private int mLastSelectedTabPosition = INVALID_TAB_POS;
public RetainableTabLayout(Context context) {
super(context);
}
public RetainableTabLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public RetainableTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void removeAllTabs() {
// Retain last selected position before removing all tabs
mLastSelectedTabPosition = getSelectedTabPosition();
super.removeAllTabs();
}
@Override
public int getSelectedTabPosition() {
// Override selected tab position to return your last selected tab position
final int selectedTabPositionAtParent = super.getSelectedTabPosition();
return selectedTabPositionAtParent == INVALID_TAB_POS ?
mLastSelectedTabPosition : selectedTabPositionAtParent;
}
}
Run Code Online (Sandbox Code Playgroud)
最后一定要在重新创建之后重新选择标签TabLayout.
findViewById(R.id.fab).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
pagerAdapter.notifyDataSetChanged();
// At the end make sure to reselect your last item.
new Handler().postDelayed(
new Runnable() {
@Override
public void run() {
final TabLayout.Tab selectedTab = tabLayout.getTabAt(
tabLayout.getSelectedTabPosition());
if (selectedTab != null) {
selectedTab.select();
}
}
}, 100);
}
});
Run Code Online (Sandbox Code Playgroud)
此问题将解决您的问题,但我认为TabLayout必须保留最后选择的位置以防数据集更改.这是我所理解的,欢迎任何评论或更多理解.
小智 6
您可以致电:
setupWithViewPager(@Nullable final ViewPager viewPager, boolean autoRefresh)
Run Code Online (Sandbox Code Playgroud)
并将参数设置autoRefresh为false.
也可以看看: TabLayout(ViewPager,boolean)
可以直接设置当前位置。
您可以在通知数据集更改之前获取所选位置并将其保存在静态变量中并每次更新:
public static tabPostion;
@Override
public void onTabSelected(TabLayout.Tab tab) {
tabPostion = tab.getPosition();
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
//set the postion of the pervious tab
yourviewpager.setCurrentItem(tabPostion);
Run Code Online (Sandbox Code Playgroud)
下面是我的项目的代码:
@Override
public void onTabSelected(TabLayout.Tab tab) {
// imageHashMap = new HashMap<>();
onClearOrSelectAllImage(FlickQuickEnum.PIC_SELECTION_ACTION.CLEAR);
selectedImageUrls = new HashMap<>();
String tag = tab.getText().toString();
String tagName = tag.substring(1, tag.length());
currentTab = tagName;
if (tagName != null) {
dbAlbumPhotoList = new ArrayList<>();
if (tagName.equals("All")) {
dbAlbumPhotoList = dbAlbumPhotosHashMap.get(album.getAlbumName());
} else {
dbAlbumPhotoList = dbAlbumPhotosHashMap.get(tagName);
}
}
updatePhotoCount();
setPhotosSelectedActions(false);
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1786 次 |
| 最近记录: |