package com.tablayout;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import static android.support.v4.view.ViewPager.SCROLL_STATE_DRAGGING;
import static android.support.v4.view.ViewPager.SCROLL_STATE_IDLE;
import static android.support.v4.view.ViewPager.SCROLL_STATE_SETTLING;
/**
* 计算不准确
* tab点击滑动,重新滑动问题
* 线问题
*/
public class MainActivity extends AppCompatActivity{
TabLayout tabLayout;
ViewPager viewPager;
View lineSeprator;
String[] tabTitles = new String[]{"Actions", "Living-room", "Actions", "Living-room", "Actions", "Actions", "Living-room", "Actions", "Living-room", "Actions"};
Method tabLayoutSetScrollPosition;
Method tabLayoutSelectTab;
boolean clickSelectable = false;
boolean scrollSelectable = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tabLayout = (TabLayout) findViewById(R.id.tabLayout);
viewPager = (ViewPager) findViewById(R.id.viewPager);
lineSeprator = findViewById(R.id.line_seprator);
ViewGroup.LayoutParams params = lineSeprator.getLayoutParams();
params.width = this.getResources().getDisplayMetrics().widthPixels / tabTitles.length;
lineSeprator.setLayoutParams(params);
viewPager.setAdapter(new TextFragAdapter(this.getSupportFragmentManager()));
tabLayout.setupWithViewPager(viewPager);
try {
tabLayoutSetScrollPosition = tabLayout.getClass().getDeclaredMethod("setScrollPosition", int.class, float.class, boolean.class, boolean.class);
tabLayoutSelectTab = tabLayout.getClass().getDeclaredMethod("selectTab", TabLayout.Tab.class, boolean.class);
tabLayoutSetScrollPosition.setAccessible(true);
tabLayoutSelectTab.setAccessible(true);
} catch (Exception e) {
e.printStackTrace();
}
for (int i = 0; i < tabTitles.length; i++) {
tabLayout.getTabAt(i).setCustomView(getCustomView(tabTitles[i], i));
}
tabLayout.setOnScrollChangeListener(new View.OnScrollChangeListener() {
@Override
public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
FV.log("scrollX:" + scrollX);
}
});
tabLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int tabCount = tabLayout.getTabCount();
for (int i = 0; i < tabCount; i++) {
View customView = tabLayout.getTabAt(i).getCustomView();
try {
TabLayout.Tab tabGet = tabLayout.getTabAt(i);
Field field = tabGet.getClass().getDeclaredField("mView");
field.setAccessible(true);
LinearLayout obj = (LinearLayout) field.get(tabGet);
FV.log("obj:" + obj.getMeasuredWidth());
} catch (Exception e) {
e.printStackTrace();
}
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) customView.getLayoutParams();
FV.log(tabTitles[i] + ",width:" + customView.getMeasuredWidth() + ",leftMargin:" + params.leftMargin + ",rightMargin:" + params.rightMargin);
}
}
});
viewPager.clearOnPageChangeListeners();
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
private final WeakReference<TabLayout> mTabLayoutRef = new WeakReference<>(tabLayout);
private int mPreviousScrollState;
private int mScrollState;
@Override
public void onPageScrollStateChanged(final int state) {
mPreviousScrollState = mScrollState;
mScrollState = state;
}
@Override
public void onPageScrolled(final int position, final float positionOffset,
final int positionOffsetPixels) {
FV.log("onPageScrolled11111111:" + position + ",clickable:" + clickSelectable + ",positionOffset:" + positionOffset);
setLineParams(position, positionOffset);
if (clickSelectable)
scrollSelectable = false;
else
scrollSelectable = true;
FV.log("onPageScrolled:" + position + ",clickable:" + clickSelectable);
final TabLayout tabLayout = mTabLayoutRef.get();
if (tabLayout != null) {
// Only update the text selection if we're not settling, or we are settling after
// being dragged
final boolean updateText = mScrollState != SCROLL_STATE_SETTLING ||
mPreviousScrollState == SCROLL_STATE_DRAGGING;
// Update the indicator if we're not settling after being idle. This is caused
// from a setCurrentItem() call and will be handled by an animation from
// onPageSelected() instead.
final boolean updateIndicator = !(mScrollState == SCROLL_STATE_SETTLING
&& mPreviousScrollState == SCROLL_STATE_IDLE);
// tabLayout.setScrollPosition(position, positionOffset, updateText, updateIndicator);
try {
if (!clickSelectable)
tabLayoutSetScrollPosition.invoke(tabLayout, position, positionOffset, updateText, updateIndicator);
} catch (Exception e) {
e.printStackTrace();
}
}
if (positionOffset == 0) {
clickSelectable = false;
scrollSelectable = false;
}
}
@Override
public void onPageSelected(final int position) {
FV.log("onPageSelected:" + position);
if (!scrollSelectable)
clickSelectable = true;
final TabLayout tabLayout = mTabLayoutRef.get();
if (tabLayout != null && tabLayout.getSelectedTabPosition() != position
&& position < tabLayout.getTabCount()) {
// Select the tab, only updating the indicator if we're not being dragged/settled
// (since onPageScrolled will handle that).
final boolean updateIndicator = mScrollState == SCROLL_STATE_IDLE
|| (mScrollState == SCROLL_STATE_SETTLING
&& mPreviousScrollState == SCROLL_STATE_IDLE);
try {
tabLayoutSelectTab.invoke(tabLayout, tabLayout.getTabAt(position), updateIndicator);
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
}
public View getCustomView(String title, int position) {
View mView = LayoutInflater.from(this).inflate(R.layout.tab_title_item_layout, null);
((TextView) mView.findViewById(R.id.title)).setText(title);
return mView;
}
private void setLineParams(int position, float positionOffset) {
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) lineSeprator.getLayoutParams();
params.leftMargin = (int) (params.width * (position + positionOffset));
lineSeprator.setLayoutParams(params);
}
}