android开发步步为营之71:CoordinatorLayout+AppBarLayout+RecyclerView+ViewPager打造可上下左右滑动的App主框架

在看过很多app之后,你会发现现在很多的app的主框架是可以上下左右滑动,左右滑动,我们自然会想到用viewpager,但是上下可以滑动,而且顶部广告或者背景划上去之后,还需要保留tab标签用什么来实现?查阅过很多资料,最终发现sdk里面android support v7有CoordinatorLayout+AppBarLayout+RecyclerView,两个组件组合可以支持上下滑动效果,另外CoordinatorLayout+AppBarLayout+NestedScrollView也可以实现上下滑动效果,但是经试验证明,NestedScrollView需要本身可以滑动,也就是里面的数据超过满屏需要滑动,才能将AppBarLayout划上去。

先给出效果图,不好意思,不知道怎么弄动态图,给出两张静态效果图。

OK,现在我们来实现这个功能,这里给出主要的步骤。

第一步:引入V7的支持库

build.gradle里面引入

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:design:22.2.0'
    compile 'com.android.support:recyclerview-v7:22.2.0'
}

    第二步:设计主页面activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    android:id="@+id/main_content"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <LinearLayout
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:background="#123456"
            app:layout_scrollFlags="scroll|enterAlways"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            android:gravity="center_vertical"
            android:orientation="vertical">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="the best app"/>
            </LinearLayout>

        <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:background="#810e88"/>

    </android.support.design.widget.AppBarLayout>
    <android.support.v4.view.ViewPager
        android:id="@+id/vp_body"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

    </android.support.v4.view.ViewPager>

</android.support.design.widget.CoordinatorLayout>

第三步:编写MainActivity.java

package com.figo.study;

import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.View;
import com.figo.study.fragment.ActivityFragment;
import com.figo.study.fragment.ExchangeFragment;
import com.figo.study.fragment.MeFragment;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends FragmentActivity {
    private ViewPager mVpBody;
    ArrayList<Fragment> fragmentsList;
    private int currIndex;
    List<String> titles;

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

    private void initViewPager() {
        try {
            TabLayout mTabLayout = (TabLayout) findViewById(R.id.tabs);
            titles = new ArrayList<>();
            titles.add("Exchange");
            titles.add("Activity");
            titles.add("Me");

            mTabLayout.addTab(mTabLayout.newTab().setText(titles.get(0)));
            mTabLayout.addTab(mTabLayout.newTab().setText(titles.get(1)));
            mTabLayout.addTab(mTabLayout.newTab().setText(titles.get(2)));

            mTabLayout.setTabTextColors(getResources().getColor(R.color.white), getResources().getColor(R.color.selected));

            mVpBody = (ViewPager) findViewById(R.id.vp_body);
            fragmentsList = new ArrayList<Fragment>();
            Bundle bundle = new Bundle();
            Fragment exchangeFragment = ExchangeFragment.newInstance(
                    MainActivity.this, bundle);
            Fragment activityFragment = ActivityFragment.newInstance(
                    MainActivity.this, bundle);
            Fragment meFragment = MeFragment.newInstance(
                    MainActivity.this, bundle);

            fragmentsList.add(exchangeFragment);
            fragmentsList.add(activityFragment);
            fragmentsList.add(meFragment);
            TabFragmentPagerAdapter tabFragmentPagerAdapter = new TabFragmentPagerAdapter(
                    getSupportFragmentManager(), fragmentsList);
            mVpBody.setAdapter(new TabFragmentPagerAdapter(
                    getSupportFragmentManager(), fragmentsList));
            mVpBody.setCurrentItem(0);
            mVpBody.setOnPageChangeListener(new MyOnPageChangeListener());

            mTabLayout.setupWithViewPager(mVpBody);
            mTabLayout.setTabsFromPagerAdapter(tabFragmentPagerAdapter);

        } catch (Exception e) {
            Log.e("initViewPager", "initViewPager", e);
        }

    }

    public class TabFragmentPagerAdapter extends FragmentPagerAdapter {
        ArrayList<Fragment> mFragmentsList;

        public TabFragmentPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        public TabFragmentPagerAdapter(FragmentManager fm, ArrayList<Fragment> fragmentsList) {
            super(fm);
            mFragmentsList = fragmentsList;
        }

        @Override
        public Fragment getItem(int position) {
            return mFragmentsList.get(position);
        }

        @Override
        public int getCount() {
            return mFragmentsList.size();
        }

        @Override
        public CharSequence getPageTitle(int position) {
            return titles.get(position);
        }
    }

    public class TabOnClickListener implements View.OnClickListener {
        private int index = 0;

        public TabOnClickListener(int i) {
            index = i;
        }

        @Override
        public void onClick(View v) {
            mVpBody.setCurrentItem(index);
        }
    }

    ;

    public class MyOnPageChangeListener implements ViewPager.OnPageChangeListener {

        @Override
        public void onPageSelected(int arg0) {

            switch (arg0) {
                case 0:

                    break;
                case 1:

                    break;
                case 2:

                    break;

            }
            currIndex = arg0;

        }

        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {
        }

        @Override
        public void onPageScrollStateChanged(int arg0) {
        }
    }
}

       第四步:编写fragment,这里给出其中一个ActivityFragment.java

package com.figo.study.fragment;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
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 com.figo.study.R;

/**
 * Activity
 */
public class ActivityFragment extends android.support.v4.app.Fragment {
    public static ActivityFragment newInstance(Context context,Bundle bundle) {
        ActivityFragment newFragment = new ActivityFragment();
        newFragment.setArguments(bundle);
        return newFragment;

    }

    private RecyclerView mRecyclerView;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        mRecyclerView =
                (RecyclerView) inflater.inflate(R.layout.fragment_activity_new, container, false);
        return mRecyclerView;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(mRecyclerView.getContext()));
        mRecyclerView.setAdapter(new RecyclerViewAdapter(getActivity()));
    }

    public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {

        private Context mContext;

        public RecyclerViewAdapter(Context mContext) {
            this.mContext = mContext;
        }

        @Override
        public RecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view =
                    LayoutInflater.from(parent.getContext()).inflate(R.layout.fragment_activity, parent, false);
            return new ViewHolder(view);
        }

        @TargetApi(Build.VERSION_CODES.LOLLIPOP)
        @Override
        public void onBindViewHolder(final RecyclerViewAdapter.ViewHolder holder, int position) {
            final View view = holder.mView;

        }

        @Override
        public int getItemCount() {
            return 1;
        }

        public  class ViewHolder extends RecyclerView.ViewHolder {
            public final View mView;

            public ViewHolder(View view) {
                super(view);
                mView = view;
            }
        }
    }

}

可以看到真正的fragment布局其实是当做recylerview的一项了。

fragment_activity_new.xml布局

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rv_activity"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

fragment_activity.xml布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Activity"
        android:id="@+id/textView"
        android:layout_gravity="center_horizontal" />
</LinearLayout>

注意一点,fragment_activity.xml里面如有listview的话,listitem的布局必须是LinearLayout,而且必须计算listview的高度,不然上下滑动的效果不管用的。

      第五步:相关的样式设计style.xml文件

<style name="Theme.DesignDemo" parent="Base.Theme.DesignDemo">
    </style>

    <style name="Base.Theme.DesignDemo" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="colorPrimary">#0fb73d</item>
        <item name="colorPrimaryDark">#0ba823</item>
        <item name="colorAccent">#FF4081</item>
        <item name="android:windowBackground">@color/window_background</item>
    </style>

第六步:AndroidManifest.xml配置

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.figo.study" >

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/Theme.DesignDemo">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

有了以上6步,相信你也可以打造上下左右都可以有滑动效果的APP了

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-09 21:14:59

android开发步步为营之71:CoordinatorLayout+AppBarLayout+RecyclerView+ViewPager打造可上下左右滑动的App主框架的相关文章

Android开发之自定义HorizontalScrollView视图实现仿ViewPager效果

开发过程中,需要达到 HorizontalScrollView和ViewPager的效果,于是直接重写了HorizontalScrollView来达到实现ViewPager的效果. 实际效果图如下: (1)自定义HorizontalScrollView类:AppHorizontalScrollView实现: package com.czm.ui.view; import java.util.ArrayList; import android.content.Context; import and

Android开发:ListView、AdapterView、RecyclerView全面解析

目录 AdapterView简介 AdapterView本身是一个抽象类,AdapterView及其子类的继承关系如下图: 特征: AdapterView继承自ViewGroup,本质是个容器 AdapterView可以包含多个"列表项",并将这多个列表项以合适的形式展示 AdapterView显示的列表项内容由Adapter提供 它派生的子类在用法上也基本相似,只是在显示上有一定区别,因此把他们也归为一类. 由AdapterView直接派生的三个类: AbsListView.AbsS

android开发步步为营之70:android接入Google Analytics总结

求人不如求己,今天项目里要接入Google Analytics,这个是做应用统计分析用的,可以查看当前手机活跃用户,事件点击等等数据,先看看效果: 之前eclipse里面接入已经成功,昨天项目组决定项目转成使用android studio来开发,看google官方文档,官方文档https://developers.google.com/analytics/devguides/collection/android/v4/,然后官方文档里面的配置文件是用google-services.json的,这

android开发步步为营之20:网络设置

网络设置这块在手机应用里面是非常重要的一块,因为一般应用都需要和外部网络做交互的.本篇文章就展示了一个比较经典应用场景.比如我最近在开发的转账应用.这个是需要和网络交互的.当用户打开应用之后,应用首先会判断用户是否已经打开wifi或者gprs网络.没有则跳转到系统的无线和网络设置界面,当用户设置好了之后,我这里做了一个更人性化的处理,创建了一个广播接收器,因为我们知道,手机在打开网络或者收到短信的时候,都会对外发布一条广播.一旦网络连接上了之后,我的这个广播接收器,就会收到信息,然后判断当前的转

android开发步步为营之58:给图片绘制圆形气泡背景效果

最近在开发项目的时候,有一个需求,需要给应用图标绘制圆形气泡背景,有了彩色气泡这样显得漂亮一点,气泡的颜色是应用图标的颜色均值,先看看效果,然后,我再给出demo. demo应用图标是这样的: 添加气泡背景后是这样的: 仔细看圆形背景颜色是图标颜色的均值. 好的,下面我们来完成这个demo. 第一步.编写页面activity_drawcycle.xml <?xml version="1.0" encoding="utf-8"?> <LinearLa

android开发步步为营之68:Facebook原生广告接入总结

开发应用的目的是干嘛?一方面当然是提供优质服务给用户,还有一方面最重要的还是须要有盈利.不然谁还有动力花钱花时间去开发app? 我们的应用主攻海外市场,所以主要还是接入国外的广告提供商.本文就今天刚完毕接入facebook原生广告功能,介绍一下怎样接入fb的原生广告.供大家參考.         第一步:申请接入账号(须要FQ) https://developers.facebook.com/docs/audience-network/getting-started#company_info h

android开发步步为营之34:四大组件之ContentProvider

ContentProvider,从字面意义上理解,内容提供者,这个类目的就是一个桥梁的作用,让一个应用的数据(SQLiteDatabase, SharedPreferences,Xml,Txt等数据),通过ContentProvider可以让其他的应用访问. 理论知识 (一).ContentProvider简介 当应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就可以向其他应用共享其数据.虽然使用其他方法也可以对外共享数据,但数据访问方式会因数据存储的方式而不同

android开发步步为营之35:GridView的用法

之前使用asp.net开发软件的过程中也使用GridView,发现android里面也有这么一个控件,使用方法有点相似,都是使用适配器将数据绑定到这个控件,然后将数据展示出来,应该说它和ListView一样,是个非常常用的控件,所以我们应该学习如何使用它,理论知识是没多少的,就是一个展示数据的控件,继承关系如下: public class GridView extends AbsListView java.lang.Object android.view.View android.view.Vi

android开发步步为营之56:Android开发技术点总结(持续更新)

1.eclipse svn插件下载 http://subclipse.tigris.org/update_1.6.x http://subclipse.tigris.org/update_1.8.x 64位机器 http://subclipse.tigris.org/servlets/ProjectProcess?pageID=p4wYuA 2.eclipse常用插件下载 http://blog.csdn.net/jackiehff/article/details/8181945 3.unico