scrollview巢狀viewpager(fragment裡有listview)
阿新 • • 發佈:2019-02-03
專案地址:
經常用到scrollview巢狀listview,
效果是:listview自己不滾動,隨著scrollview的滾動而滾動。
但是有個需求是scrollview巢狀viewpager,viewpager有三個fragment,fragment裡有listview。
MainActivity佈局
<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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:fillViewport="true"
tools:context="example.com.myvplvsv.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation ="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_gravity="center"
android:gravity="center"
android:text="Hello World!"
android:textColor="@color/colorAccent"
android:textSize ="25sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#e9e9e9"
android:orientation="vertical">
<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginTop="12dp">
<TextView
android:id="@+id/tab1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="@string/tab1"
android:textColor="#cccccc"
android:textSize="10sp" />
<TextView
android:id="@+id/tab2"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="@string/tab2"
android:textColor="#cccccc"
android:textSize="10sp" />
<TextView
android:id="@+id/tab3"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="@string/tab3"
android:textColor="#cccccc"
android:textSize="10sp" />
</LinearLayout>
<View
android:id="@+id/cursor"
android:layout_width="150dp"
android:layout_height="3dp"
android:background="#ff7012" />
</LinearLayout>
<example.com.myvplvsv.view.ViewPagerForScrollView
android:id="@+id/vp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ff4081" />
</LinearLayout>
</ScrollView>
知識點:
1、動畫改變字型大小: tab2.animate().scaleX(1.5f).scaleY(1.5f).setDuration(200);
2、佈局管理器的使用改變view的位置、大小等
3、viewpager的addOnPageChangeListener監聽。
參考:
MainActivity:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final int TAB_COUNT = 3;
private TextView tab1;
private TextView tab2;
private TextView tab3;
private ViewPager mVp;
private int offset = 0;//初始位置
private View cursor;
private int scrollWidth;
private int currentIndex;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViews();
setListener();
initVp();
initTabs();
}
private void setListener() {
tab1.setOnClickListener(this);
tab2.setOnClickListener(this);
tab3.setOnClickListener(this);
}
private void findViews() {
tab1 = (TextView) findViewById(R.id.tab1);
tab2 = (TextView) findViewById(R.id.tab2);
tab3 = (TextView) findViewById(R.id.tab3);
cursor = findViewById(R.id.cursor);
mVp = ((ViewPager) this.findViewById(R.id.vp));
}
private void initTabs() {
//將頂部文字恢復預設值
setTabsColor(tab1);
tab1.animate().scaleX(1.5f).scaleY(1.5f).setDuration(0);//設定時長為0
//螢幕寬度
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int screenW = dm.widthPixels;
//指示器滾動間隔
scrollWidth = screenW / 3;
//指示器寬度設定
int cursorWidth = (screenW / 6);
//指示器初始位置
offset = (screenW / TAB_COUNT - cursorWidth) / 2;
//佈局管理器使用方法一:
// LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(cursor.getLayoutParams());
// layoutParams.width = cursorWidth;
// layoutParams.setMargins(offset, 0, 0, 0);
// cursor.setLayoutParams(layoutParams);
//佈局管理器使用方法二:
LinearLayout.LayoutParams cursorLayoutParams = (LinearLayout.LayoutParams) cursor.getLayoutParams();
cursorLayoutParams.width = cursorWidth;
cursorLayoutParams.leftMargin = offset;
cursor.setLayoutParams(cursorLayoutParams);
}
private void initVp() {
ArrayList<Fragment> fragmentLists = new ArrayList<>();
fragmentLists.add(new Fragment1());
fragmentLists.add(new Fragment2());
fragmentLists.add(new Fragment3());
FragmentManager fragmentManager = getSupportFragmentManager();
mVp.setFocusable(false);
mVp.setAdapter(new MyAdapter(fragmentManager, fragmentLists));
mVp.setOffscreenPageLimit(2);
mVp.setCurrentItem(0);
mVp.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
switch (position) {
//成功左滑一頁(0到1):
// onPageScrolled執行,positionOffset從0開始變大,此時position=0,currentIndex=0
// onPageSelected執行:currentIndex變為1,此時position=0,currentIndex=1
// onPageScrolled繼續執行,positionOffset從0開始變大直到無限接近1,此時position=0,currentIndex=1
// 最後onPageScrolled繼續執行,positionOffset從無限接近1突然恢復到0,此時position=1,currentIndex=1
case 0:
if (currentIndex == 0) {
setIndicatorPosition(offset + (int) (scrollWidth * positionOffset));
Log.e("000", "0-->currentIndex == 0");
} else if (currentIndex == 1) {
setIndicatorPosition(offset + (int) (scrollWidth * (positionOffset)));
Log.e("000", "0-->currentIndex == 1");
}
break;
case 1:
if (currentIndex == 1) {
setIndicatorPosition(offset + scrollWidth + (int) (scrollWidth * positionOffset));
Log.e("000", "1-->currentIndex == 1");
} else if (currentIndex == 2) {
setIndicatorPosition(offset + scrollWidth + (int) (scrollWidth * (positionOffset)));
Log.e("000", "1-->currentIndex == 2");
}
break;
case 2:
if (currentIndex == 2) {
setIndicatorPosition(offset + scrollWidth * 2);
Log.e("000", "2-->currentIndex == 2");
}
break;
}
}
@Override
public void onPageSelected(int position) {
currentIndex = position;//已選中位置:012
Log.e("000", "onPageSelected==currentIndex==" + currentIndex);
switch (position) {
case 0:
tab1.animate().scaleX(1.5f).scaleY(1.5f).setDuration(200);
tab2.animate().scaleX(1.0f).scaleY(1.0f).setDuration(200);
tab3.animate().scaleX(1.0f).scaleY(1.0f).setDuration(200);
setTabsColor(tab1);
// setIndicatorPosition(offset);
break;
case 1:
tab2.animate().scaleX(1.5f).scaleY(1.5f).setDuration(200);
tab1.animate().scaleX(1.0f).scaleY(1.0f).setDuration(200);
tab3.animate().scaleX(1.0f).scaleY(1.0f).setDuration(200);
setTabsColor(tab2);
// setIndicatorPosition(offset + scrollWidth);
break;
case 2:
tab3.animate().scaleX(1.5f).scaleY(1.5f).setDuration(200);
tab2.animate().scaleX(1.0f).scaleY(1.0f).setDuration(200);
tab1.animate().scaleX(1.0f).scaleY(1.0f).setDuration(200);
setTabsColor(tab3);
// setIndicatorPosition(offset + scrollWidth * 2);
break;
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
private void setIndicatorPosition(int offset) {
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(cursor.getLayoutParams());
layoutParams.setMargins(offset, 0, 0, 0);
cursor.setLayoutParams(layoutParams);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.tab1:
mVp.setCurrentItem(0);
break;
case R.id.tab2:
mVp.setCurrentItem(1);
break;
case R.id.tab3:
mVp.setCurrentItem(2);
break;
}
}
private void setTabsColor(TextView textView) {
tab1.setTextColor(ContextCompat.getColor(this, R.color.defalut_color));
tab2.setTextColor(ContextCompat.getColor(this, R.color.defalut_color));
tab3.setTextColor(ContextCompat.getColor(this, R.color.defalut_color));
textView.setTextColor(ContextCompat.getColor(this, R.color.select_color));
}
}
ViewPagerForScrollView
解決viewpager(內含listview)隨scrollview一起滑動
/**
* ScrollView巢狀viewpager
*/
public class ViewPagerForScrollView extends ViewPager {
public ViewPagerForScrollView(Context context) {
super(context);
}
public ViewPagerForScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int height = 0;
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
int h = child.getMeasuredHeight();
if (h > height)
height = h;
}
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
MyListView
解決listview不顯示
public class MyListView extends ListView {
public MyListView(Context context) {
super(context);
}
public MyListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
/**
* 自適應
*/
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}
Fragment1
需設定 mLv.setFocusable(false);解決不置頂的問題
public class Fragment1 extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = LayoutInflater.from(getActivity()).inflate(R.layout.fragment1_layout, container, false);
ListView mLv = ((ListView) view.findViewById(R.id.lv));
mLv.setDivider(new ColorDrawable(Color.parseColor("#ff0000")));
mLv.setDividerHeight(5);
mLv.setFocusable(false);
return view;
}
}
最後
這樣就實現了viewpager隨scrollview一起滾動 ,但是還有一個問題就是如果三個fragment頁面的listview高度不統一,那麼fragment將依靠最高的那一個為準,也就是說會有比較矮的fragment有空白。
比如: