今天在项目中,遇见实现类似360软件详情页的效果,结合现在比较流行的Material design,采用了CoordinatorLayout来实现这个效果,跟大家分享一下。
首先,看一下需求的效果,由于不会搞gif图,所以图是从翔哥那抠出来的,效果是一样的。
中部导航栏在滑上去后会顶在窗口顶部,隐藏顶部部分,下拉的时候又将顶部显示出来,这样的效果,现在也比较常见了,现在带大家了解一下我的实现方式
首先,必须添加design依赖
//noinspection GradleCompatible compile 'com.android.support:design:24.0.0-alpha1'1212
然后就是如何布局了
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="test1.up72.com.myapplication.MainActivity"> <android.support.design.widget.CoordinatorLayout 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:background="@color/white"> <FrameLayout android:layout_width="match_parent" android:layout_height="208dp" android:background="@color/grey_200" app:layout_scrollFlags="scroll|enterAlways|snap"> <View android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/ic_bg_daobo" /> </FrameLayout> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="@color/grey_300" /> <android.support.design.widget.TabLayout android:id="@+id/tabLayout" android:layout_width="match_parent" android:layout_height="wrap_content" app:tabGravity="fill" app:tabIndicatorColor="@color/colorPrimary" app:tabSelectedTextColor="@color/colorPrimary" app:tabTextColor="@color/grey_900" /> </android.support.design.widget.AppBarLayout> <android.support.v4.view.ViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> </android.support.design.widget.CoordinatorLayout> </LinearLayout>
这里讲解一下,整个布局其实都是被CoordinatorLayout包裹。
CoordinatorLayout的作用
一:作为顶层布局。
二:协调子布局。
AppBarLayout 是继承LinerLayout实现的一个ViewGroup容器组件,它是为了Material Design设计的App Bar,
支持手势滑动操作。
默认的AppBarLayout是垂直方向的,它的作用是把AppBarLayout包裹的内容都作为AppBar。
AppBarLayout是支持手势滑动效果的,不过的跟CoordinatorLayout配合使用
以上是大神讲解的,比我说的清楚。简而言之
CoordinatorLayout与AppBarLayout结合使用来实现手势的滑动效果。
要实现滑动效果,有三个必须实现条件。
1.必须设置CoordinatorLayout作为顶层布局
2.必须将滑动隐藏布局设置 app:layout_scrollFlags=”scroll|enterAlways”属性,”scroll|exitUntilCollapsed”也可以,只不过实现效果不一样。
3.将滑动的view设置app:layout_behavior=”@string/appbar_scrolling_view_behavior”属性
上面可以看出Flamelayout实现条件2,viewPager实现条件3
scroll: 所有想滚动出屏幕的view都需要设置这个flag,没有设置这个flag的view将被固定在屏幕顶部。例如,TabLayout 没有设置这个值,将会停留在屏幕顶部。
enterAlways:设置这个flag时,向下的滚动都会导致该view变为可见,启用快速“返回模式”。
enterAlwaysCollapsed: 当你的视图已经设置minHeight属性又使用此标志时,你的视图只能已最小高度进入,只有当滚动视图到达顶部时才扩大到完整高度。
package test1.up72.com.myapplication;import android.support.design.widget.TabLayout;import android.support.v4.app.Fragment;import android.support.v4.view.ViewPager;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import java.util.ArrayList;public class MainActivity extends AppCompatActivity { private TabLayout tabLayout; private FragmentAdapter adapter; private ViewPager viewPager; private String title[]; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); viewPager = (ViewPager) findViewById(R.id.viewPager); tabLayout = (TabLayout) findViewById(R.id.tabLayout); title = this.getResources().getStringArray(R.array.star_user_info); viewPager.setAdapter(adapter = new FragmentAdapter(getSupportFragmentManager(), this, getFragments(), title)); tabLayout.setupWithViewPager(viewPager); tabLayout.setTabMode(TabLayout.MODE_FIXED); } private ArrayList<Fragment> getFragments() { ArrayList<Fragment> fragments = new ArrayList<>(); fragments.add(new Fragment1()); fragments.add(new Fragment2()); fragments.add(new Fragment3()); return fragments; } }
这里就很简单啦,Tablayout,ViewPager,三个Fragment,然后在里面实现RecylerView效果
Fragmen实现列表效果,填充数据
package test1.up72.com.myapplication;import android.os.Bundle;import android.support.annotation.Nullable;import android.support.v4.app.Fragment;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import java.util.ArrayList;/** * Created by wangchang on 2016/3/31. */public class Fragment1 extends Fragment { private RecyclerView recyclerView; private NewAdapter adapter; @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_eye, container, false); } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); recyclerView = (RecyclerView) getActivity().findViewById(R.id.recylerview); recyclerView.setHasFixedSize(true); recyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false)); recyclerView.setAdapter(adapter = new NewAdapter()); adapter.replaceAll(getData()); } public ArrayList<NewsModel> getData() { ArrayList<NewsModel> list = new ArrayList<>(); for (int i = 0; i < 20; i++) { NewsModel model = new NewsModel(); model.setItem("简介" + i); list.add(model); } return list; } }
适配器的实现
package test1.up72.com.myapplication;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;import java.util.ArrayList;/** * Created by wangchang on 2016/3/29. */public class NewAdapter extends RecyclerView.Adapter<NewAdapter.BaseViewHolder> { private ArrayList<NewsModel> dataList = new ArrayList<>(); public void replaceAll(ArrayList<NewsModel> list) { dataList.clear(); if (list != null) { dataList.addAll(list); } notifyDataSetChanged(); } @Override public NewAdapter.BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { return new NewViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_new_list, parent, false)); } @Override public void onBindViewHolder(NewAdapter.BaseViewHolder holder, int position) { holder.setData(dataList.get(position)); } @Override public int getItemCount() { return dataList != null ? dataList.size() : 0; } public class BaseViewHolder extends RecyclerView.ViewHolder { public BaseViewHolder(View itemView) { super(itemView); } void setData(Object data) { } } private class NewViewHolder extends BaseViewHolder { private TextView tv; public NewViewHolder(View view) { super(view); tv = (TextView) view.findViewById(R.id.tv); } @Override void setData(Object data) { if (data != null) { NewsModel model = (NewsModel) data; tv.setText(model.getItem()); } } } }
这里设置exitUntilCollapsed,enterAlways会实现两种不同的滑动效果,exitUntilCollapsed会实现当滑动列表滑到顶端才会实现隐藏效果,enterAlways会实现只有上滑就会隐藏顶部的效果。
附上代码下载地址