您的位置:首页 > 移动开发

Android基础学习总结(七)——简单实现新闻选项卡滑动效果(CoordinatorLayout+AppBarLayout+Toolbar+TabLayout+ViewPager大合成)

2018-01-29 17:08 711 查看

引言

曾经看到网易、头条新闻就想自己实现一下效果,结果花费了不少时间,基础不牢,地动山摇,现在一步步深入学习Android后发现实现一下也不难,现在就简单记录下自己的实现思路和方法,供自己以后参考。

实现思路

首先能看到的应该是三个部分Toolbar+TabLayout+ViewPager,再细分下去,ViewPager包含了一个Recyclerview,里面有很多itemview来显示和滑动,往大了看,还有AppBarLayout包裹Toolbar和TabLayout作为顶部栏,最后整个包上CoordinatorLayout协调其所包裹的子view的手势操作的,大致就酱,具体实现下面一步步看。

关于ViewPager

1.一个页面切换的组件,可以往里面填充多个View,可以通过触摸屏幕左右滑动来切换不同的View,官方连接ViewPager ,和大多数情况一样需要一个Adapter适配器,将要显示的View和ViewPager绑定,由于官方建议使用Fragment来填充ViewPager这样方便生成与管理生命周期等等,一般主要使用FragmentPageAdapter,它的缓存机制是缓存当前页,前一页和后一页共3页这样。

2.使用PagerAdapter的重要方法:

getCount( ):获得viewpager中有多少个view

destroyItem( ):移除一个给定位置的页面。适配器有责任从容器中删除这个视图。这是为了确保在finishUpdate(viewGroup)返回时视图能够被移除。

instantiateItem( ):①将给定位置的view添加到ViewGroup(容器)中,创建并显示出来 ②返回一个代表新增页面的Object(key),通常都是直接返回view本身就可以了,当然你也可以自定义自己的key,但是key和每个view要一一对应的关系

isViewFromObject( ):判断instantiateItem(ViewGroup, int)函数所返回来的Key与一个页面视图是否是代表的同一个视图(即它俩是否是对应的,对应的表示同一个View),通常我们直接写return view == object;就可以了,至于为什么要这样讲起来比较复杂,后面有机会进行了解吧,貌似是ViewPager中有个存储view状态信息的ArrayList,根据View取出对应信息的吧!

关于AppBarLayout

AppBarLayout控件,它是继承LinerLayout实现的一个ViewGroup容器组件,是为了Material Design而设计的App Bar,支持手势滑动操作。

默认的AppBarLayout是垂直方向的,它的作用是把AppBarLayout包裹的内容都作为AppBar。

使用方式非常简单,直接在布局文件中包裹想要作为顶部栏的控件,例如Toolbar和TabLayout.

关于CoordinatorLayout

CoordinatorLayout是一个增强型的FrameLayout,它的作用就是用来协调其所包裹的子view的手势操作的.

为了达到手势动画效果,我们必须做如下设置,通过app:layout_scrollFlags=”scroll|enterAlways” 属性来确定哪个组件是可滑动的.关于layout_scrollFlags的属性设置,在布局文件中描述,这里就不多说了.

同时,为了使得Toolbar可以滑动,我们必须还得有个条件,就是CoordinatorLayout布局下包裹一个可以滑动的布局,比如: RecyclerView,NestedScrollView(ListView,ScrollView不支持)具有滑动效果的组件。并且还需要给这些组件设置如下属性来告诉CoordinatorLayout

app:layout_behavior="@string/appbar_scrolling_view_behavior"


该组件是带有滑动行为的组件,然后CoordinatorLayout在接受到滑动时会通知AppBarLayout中可滑动的Toolbar可以滑出屏幕了。

关于TabLayout

TabLayout是design库提供的控件,可以方便的使用指示器,功能类似ViewPagerIndicator.

使用非常方便,Android Studio只需要在gradle中引入design即可使用.

来看看配合ViewPager的使用方式,实现如下效果图:



app:tabGravity=”center” 对齐方式,可选fill和center

app:tabIndicatorColor=”@color/colorAccent” 设置tab下划线的颜色

app:tabMode=”scrollable” scrollable是可以横行滚动,fixed是指固定个数

app:tabSelectedTextColor=”@color/colorPrimaryDark” 选择tab的文本颜色

app:tabTextColor=”@color/colorPrimary” 普通tab字体颜色

//1.支持添加字符串文本tab
//tabLayout.addTab(tabLayout.newTab().setText("TAB" + i));

//2.支持添加图片tab
//tabLayout.addTab(tabLayout.newTab().setIcon(R.mipmap.ic_launcher));

//3.支持添加View
View tabView = View.inflate(TabLayoutOnlyActivity.this, R.layout.view_tab, null);
((TextView)tabView.findViewById(R.id.tv_title)).setText("TAB" + i);
tabLayout.addTab(tabLayout.newTab().setCustomView(tabView));


关于Toolbar和Recyclerview

这部分可以参考我之前的文章(✿◡‿◡)

Toolbar

Recyclerview

开始大合成

1.使用之前,别忘了在gradle中引入Material Design支持包

compile 'com.android.support:design:25.3.1'


另外,由于使用了Toolbar需要修改style中的ActionBar

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">


2.直接看完整布局activity_main.xm
4000
l:

<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:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="study.test6.MainActivity">

<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!--标题栏
设置的layout_scrollFlags有如下几种选项:
scroll: 所有想滚动出屏幕的view都需要设置这个flag-没有设置这个flag的view将被固定在屏幕顶部。
enterAlways: 这个flag让任意向下的滚动都会导致该view变为可见,启用快速“返回模式”。
enterAlwaysCollapsed: 当你的视图已经设置minHeight属性又使用此标志时,
你的视图只能以最小高度进入,只有当滚动视图到达顶部时才扩大到完整高度。
exitUntilCollapsed: 滚动退出屏幕,最后折叠在顶端。-->
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#c0f9d0"
app:layout_scrollFlags="scroll|enterAlways"
/>
<!--选项卡-->
<android.support.design.widget.TabLayout
android:id="@+id/tablayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabGravity="center"
android:background="#c0f9d0"
app:tabIndicatorColor="@color/colorAccent"
app:tabMode="scrollable"
app:tabSelectedTextColor="@color/colorPrimaryDark"
app:tabTextColor="@color/colorPrimary"
/>
</android.support.design.widget.AppBarLayout>
<!--包含可滑动的布局内容(RecyclerView,NestedScrollView,不支持ListView,ScrollView)
必须要设置app:layout_behavior="@string/appbar_scrolling_view_behavior"
属性来告知CoordinatorLayout该组件是带有滑动行为的组件,
然后CoordinatorLayout在接受到滑动时会通知AppBarLayout中可滑动的Toolbar可以滑出屏幕,
这个滑动布局RecyclerView我写在fragment -->
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
>
</android.support.v4.view.ViewPager>
</android.support.design.widget.CoordinatorLayout>


3.fragment.xml

fragment的布局就简单包含一个RecyclerView

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>

<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>


item.xml

这个是用来显示的item

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/list_item">
<ImageView
android:id="@+id/image"
android:layout_width="80dp"
android:layout_height="80dp"
/>
<TextView
android:id="@+id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>


4.接着给ViewPager弄个适配器

mFragmentPagerAdapter.java

public class mFragmentPagerAdapter extends FragmentPagerAdapter {
private MyFragment myFragment =null;
public mFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
myFragment =new MyFragment();
//这里可以根据位置返回相应的Fragment,例如娱乐,体育,新闻等等单独弄个Fragment
myFragment.setTitle("This is "+position);
return myFragment;
}
@Override
public CharSequence getPageTitle(int position) {     //返回Tab名字
String name ="Tag"+position;
return  name;
}
@Override
public int getCount() {
return 6;           //这里就简单返回个固定数字,可以根据需要返回Tab的数量
}

}


5.配置好RecyclerAdapter

主要就是自定义个MyViewHolder,具体配置看代码:

RecyclerAdapter.java

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder> {
static class MyViewHolder extends RecyclerView.ViewHolder
{
private TextView textView;
private ImageView   imageView;
public MyViewHolder(View itemview)
{
super(itemview);
textView= (TextView) itemview.findViewById(R.id.content);
imageView= (ImageView) itemview.findViewById(R.id.image);

}
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item,parent,false);
MyViewHolder viewHolder =new MyViewHolder(view);//实例化viewholder
return viewHolder;
}
@Override
public void onBindViewHolder(MyViewHolder myViewHolder, int position) {
myViewHolder.textView.setText("Test"+position);
myViewHolder.imageView.setImageResource(R.drawable.back);
}
@Override
public int getItemCount() {
return 15;          //返回个每页的数量
}
}


6.自定义MyFragment

public class MyFragment extends Fragment {

private String Title;   //可以根据这个修改item里面的内容
private RecyclerView recyclerView;
public void setTitle(String title) {
Title = title;
}

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,  Bundle savedInstanceState) {
//拿到fragment的view,之后实例化recyclerView,然后创建适配器,再挂上recyclerView
View view =inflater.inflate(R.layout.fragment,container,false);
recyclerView= (RecyclerView) view.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
RecyclerAdapter recyclerAdapter=new RecyclerAdapter();
recyclerView.setAdapter(recyclerAdapter);

return view;
}
}


7.最后是主代码MainActivity.java

主要就是初始化布局,以及关联viewPager和tablayout并且配置好相应的适配器

public class MainActivity extends AppCompatActivity {

private TabLayout tabLayout;
private ViewPager viewPager;
private mFragmentPagerAdapter mFragPAdapter;
private Toolbar toolbar;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}

private void initView() {
tabLayout = (TabLayout) findViewById(R.id.tablayout);
viewPager = (ViewPager) findViewById(R.id.viewPager);
toolbar = (Toolbar) findViewById(R.id.toolbar);

setSupportActionBar(toolbar);
mFragPAdapter=new mFragmentPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(mFragPAdapter);
tabLayout.setupWithViewPager(viewPager);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu,menu);
return true;
}
}


最终效果

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐