Android CoordinatorLayout實現多列表切換並和頭佈局聯動;
阿新 • • 發佈:2018-11-29
注意:不是雙列表聯動,是多列表和頭佈局聯動;
大概就是和餓了麼店鋪首頁類似的佈局框架吧,頭佈局顯示時,列表RecyclerView或ScrollView和頭佈局一起滾動,頭佈局完全隱藏後列表再去滾動,可以多個列表切換;
有空再上圖看效果吧;
1、主要的佈局檔案,註釋寫的很清楚;
<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <android.support.design.widget.AppBarLayout android:id="@+id/appbar" android:layout_width="match_parent" android:layout_height="222dp"> <!--最為重要的屬性就是 app:layout_scrollFlags :設定上半部分滑動的方式 1.scroll 表示CollapsingToolbarLayout可以滾動(不設定的話頭部的ImageView將不能摺疊) 2.enterAlways 表示底部的滾動控制元件只要向下滾動,頭部就顯示出來 3.enterAlwaysCollapsed 表示當底部滾動控制元件滾動見頂時,頭部顯示出來 4.exitUntilCollapsed 表示頭部摺疊到最小高度時(Toolbar的高度),就不再摺疊 5.snap 表示在滑動過程中如果停止滑動,則頭部會就近摺疊(要麼恢復原狀,要麼摺疊成一個Toolbar)--> <!--app:contentScrim="@color/colorWhite" 摺疊後的顏色--> <android.support.design.widget.CollapsingToolbarLayout android:layout_width="match_parent" app:contentScrim="@color/colorWhite" app:layout_scrollFlags="scroll|exitUntilCollapsed" android:layout_height="match_parent"> <!--app:layout_collapseParallaxMultiplier="0.6" 視差效果--> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/banner" app:layout_collapseMode="parallax" app:layout_collapseParallaxMultiplier="0.6" ></RelativeLayout> <!--app:layout_collapseMode="pin" Toolbar的狀態,是否一直顯示--> <android.support.v7.widget.Toolbar app:layout_collapseMode="pin" app:contentInsetStart="0dp" android:layout_width="match_parent" android:layout_height="48dp"> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:background="#00ffffff" android:text="點選開始搜尋" android:textSize="16dp" android:gravity="center" android:id="@+id/tv" ></TextView> </android.support.v7.widget.Toolbar> </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout> <!--app:layout_behavior="@string/appbar_scrolling_view_behavior" 在整體佈局的下面--> <RelativeLayout app:layout_behavior="@string/appbar_scrolling_view_behavior" android:layout_width="match_parent" android:background="@color/colorWhite" android:layout_height="match_parent"> <android.support.design.widget.TabLayout android:id="@+id/tab" android:layout_width="match_parent" android:layout_height="46dp"> </android.support.design.widget.TabLayout> <c.c.b.listortoolbar.NotConflictViewPager android:id="@+id/vp" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@id/tab" ></c.c.b.listortoolbar.NotConflictViewPager> </RelativeLayout> </android.support.design.widget.CoordinatorLayout>
2、該佈局中的Activity寫法:
public class MainActivity extends AppCompatActivity { private TabLayout tabLayout; private NotConflictViewPager vp; private TextView tv; private AppBarLayout appbar; private List<String> datas = Arrays.asList("呢呢","嘿嘿","哈哈"); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tabLayout = (TabLayout)findViewById(R.id.tab); vp = (NotConflictViewPager)findViewById(R.id.vp); tv = (TextView) findViewById(R.id.tv); appbar = (AppBarLayout) findViewById(R.id.appbar); tabLayout.setupWithViewPager(vp); vp.setAdapter(new Ap(getSupportFragmentManager())); appbar.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() { @Override public void onOffsetChanged(AppBarLayout appBarLayout, int i) { if (i == 0){ //開啟 tv.setTextColor(getResources().getColor(R.color.colorWhite)); }else if (Math.abs(i) >= appbar.getTotalScrollRange()){ //摺疊 tv.setTextColor(getResources().getColor(R.color.defaultTextview)); }else { // 中間 } } }); } class Ap extends FragmentStatePagerAdapter{ public Ap(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int i) { return new cFragment(datas.get(i)); } @Override public int getCount() { return datas.size(); } @Nullable @Override public CharSequence getPageTitle(int position) { return datas.get(position); } } }
3、填充ViewPager的Fragment;
R.layout.fragment_c (子條目的layout就不寫了,隨便一個有內容的佈局就行)
<?xml version="1.0" encoding="utf-8"?> <FrameLayout 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" tools:context=".cFragment"> <android.support.v7.widget.RecyclerView android:id="@+id/rv" android:layout_width="match_parent" android:layout_height="match_parent"></android.support.v7.widget.RecyclerView> </FrameLayout>
public class cFragment extends Fragment {
public cFragment() {
}
private String title;
@SuppressLint("ValidFragment")
public cFragment(String title) {
this.title = title;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_c, container, false);
initView(v);
return v;
}
private void initView(View view) {
RecyclerView rv = view.findViewById(R.id.rv);
if("嘿嘿".equals(title)){
rv.setLayoutManager(new GridLayoutManager(getActivity(),2));
rv.addItemDecoration(new GridDividerItemDecoration(getActivity())); //分割線,報錯刪除就行了;
}else {
rv.addItemDecoration(new DividerItemDecoration(getActivity(),1));
rv.setLayoutManager(new LinearLayoutManager(getActivity()));
}
rv.setAdapter(new Ap());
}
class Ap extends RecyclerView.Adapter<Ap.Vh>{
@Override
public Vh onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
return new Vh(LayoutInflater.from(getContext()).inflate(R.layout.item_rv, viewGroup, false));
}
@Override
public void onBindViewHolder(@NonNull Vh vh, int i) {
vh.tv.setText(title);
}
@Override
public int getItemCount() {
return 20;
}
class Vh extends RecyclerView.ViewHolder{
TextView tv;
public Vh(@NonNull View itemView) {
super(itemView);
tv = itemView.findViewById(R.id.tv);
}
}
}
}
列表和ViewPager衝突解決;
public class NotConflictViewPager extends ViewPager {
public NotConflictViewPager(Context context) {
super(context);
}
public NotConflictViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
private float mX;
private float mY;
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
switch (ev.getAction()){
case MotionEvent.ACTION_DOWN:
mX = ev.getX();
mY = ev.getY();
getParent().requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_MOVE:
if (Math.abs(mX-ev.getX())> Math.abs(mY-ev.getY())){
getParent().requestDisallowInterceptTouchEvent(true);
}else{
getParent().requestDisallowInterceptTouchEvent(false);
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
getParent().requestDisallowInterceptTouchEvent(false);
break;
}
return super.dispatchTouchEvent(ev);
}
}