Android AppBarLayout+TabLayout+RecyclerView+ViewPager+Fragment

最近有人讓我幫忙實現一個如下圖所示的效果
實現的效果圖
需求:標題欄本來是在banner的下方,當滑動下面的RecyclerView的時候標題欄會隨着向上移動,但是當標題欄移動到頂部時是要懸浮在頂部,下面無論如何上滑標題攔都不再移動,當向下滑動時知直到出現RecyclerView的第一條時標題欄纔會隨着向下移動。
AppBarLayout 是繼承LinerLayout實現的一個ViewGroup容器組件,它是爲了Material Design設計的App Bar,支持手勢滑動操作。CoordinatorLayout是一個增強型的FrameLayout。它的作用有兩個作爲一個佈局的根佈局 最後一個爲子視圖之間相互協調手勢效果的一個協調佈局
爲了達到上面效果圖的手勢動畫效果,我們必須做如下設置,通過app:layout_scrollFlags=”scroll” 屬性來確定哪個組件是可滑動的
設置的layout_scrollFlags有如下幾種選項:
scroll: 所有想滾動出屏幕的view都需要設置這個flag- 沒有設置這個flag的view將被固定在屏幕頂部。 enterAlways: 這個flag讓任意向下的滾動都會導致該view變爲可見,啓用快速“返回模式”。 enterAlwaysCollapsed: 當你的視圖已經設置minHeight屬性又使用此標誌時,你的視圖只能已最小高度進入,只有當滾動視圖到達頂部時才擴大到完整高度。 exitUntilCollapsed: 滾動退出屏幕,最後摺疊在頂端。
我們上面的佈局中 給Toolbar設置了app:layout_scrollFlags屬性,因此,Toolbar是可以滾動出屏幕,且向下滾動有可以出現。
具體實現的代碼如下

package com.lyx.demo.fragment;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Toast;


import com.lyx.demo.adapter.MyRecyclerViewAdapter;
import com.lyx.demo.R;
import com.lyx.demo.listener.MyItemClickListener;
import com.lyx.demo.view.LoadMoreRecyclerView;

public class FragmentPopularity extends Fragment {
    private View view;
    private SwipeRefreshLayout swipeRefreshLayout;
    private static FragmentPopularity instance=null;
    public static FragmentPopularity newInstance() {
        if(instance==null){
            instance= new FragmentPopularity();
        }
        return instance;
    }
    public FragmentPopularity(){

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.fragment_layout, container, false);
        final LoadMoreRecyclerView mRecyclerView = (LoadMoreRecyclerView) view.findViewById(R.id.recycler_view);
        mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
        mRecyclerView.setItemAnimator(new DefaultItemAnimator());
        int[]mImgList = new int[]{R.drawable.g1,R.drawable.g2,R.drawable.g3,R.drawable.g4,R.drawable.g5,R.drawable.g6,R.drawable.g7,R.drawable.g8,R.drawable.g9,R.drawable.g10};
        String [] mTag = getActivity().getResources().getStringArray(R.array.test);
        MyRecyclerViewAdapter adapter = new MyRecyclerViewAdapter(getActivity(),mImgList,mTag);
        mRecyclerView.setAdapter(adapter);
        adapter.setOnItemClickListener(new MyItemClickListener() {
            @Override
            public void onItemClick(View view, int postion) {
                Toast.makeText(getActivity(),"test"+postion,Toast.LENGTH_SHORT).show();
            }
        });
        mRecyclerView.setAutoLoadMoreEnable(true);
        mRecyclerView.setLoadMoreListener(new LoadMoreRecyclerView.LoadMoreListener() {
            @Override
            public void onLoadMore() {
                mRecyclerView.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        swipeRefreshLayout.setRefreshing(false);
                        Toast.makeText(getActivity(),"加載更多",Toast.LENGTH_SHORT).show();
                        //TODO 下面註釋掉的代碼中的false是當數據加載完成以後爲false的,然後加載更多的條目就會隱藏。
//                        mRecyclerView.notifyMoreFinish(false);
                    }
                }, 1000);
            }
        });
        swipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.refresh_layout);
        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                swipeRefreshLayout.setRefreshing(false);
                Toast.makeText(getActivity(),"刷新",Toast.LENGTH_SHORT).show();
            }
        });
        return view;
    }
}

其他的fragment內容都是複製的這個fragment的
下面的是主activity的

package com.lyx.demo.activities;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.widget.ImageView;
import android.widget.LinearLayout;

import com.lyx.demo.R;
import com.lyx.demo.adapter.BannerAdapter;
import com.lyx.demo.adapter.MyViewPagerAdapter;
import com.lyx.demo.fragment.FragmentLowPrice;
import com.lyx.demo.fragment.FragmentHighPrice;
import com.lyx.demo.fragment.FragmentPopularity;
import com.lyx.demo.fragment.FragmentSecondsOpen;
import com.lyx.demo.fragment.FragmentNewProduct;
import com.lyx.demo.utils.DensityUtil;

import java.util.ArrayList;
import java.util.List;


public class MainActivity extends AppCompatActivity {
    LinearLayout llIndexContainer;
    private List<String> mADParseArray;
    private final int HOME_AD_RESULT = 1;
    private ViewPager vp_shuffling;
    private Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                // 廣告
                case HOME_AD_RESULT:
                    vp_shuffling.setCurrentItem(vp_shuffling.getCurrentItem() + 1,
                            true);
                    break;
            }
        };
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        ViewPager mViewPager = (ViewPager) findViewById(R.id.viewpager);
        MyViewPagerAdapter viewPagerAdapter = new MyViewPagerAdapter(getSupportFragmentManager());
        viewPagerAdapter.addFragment(FragmentPopularity.newInstance(), "人氣");//添加Fragment
        viewPagerAdapter.addFragment(FragmentNewProduct.newInstance(), "新品");
        viewPagerAdapter.addFragment(FragmentSecondsOpen.newInstance(), "秒開");
        viewPagerAdapter.addFragment(FragmentHighPrice.newInstance(), "高價");
        viewPagerAdapter.addFragment(FragmentLowPrice.newInstance(), "低價");
        mViewPager.setAdapter(viewPagerAdapter);//設置適配器

        TabLayout mTabLayout = (TabLayout) findViewById(R.id.tabLayout);
        mTabLayout.addTab(mTabLayout.newTab().setText("人氣"));//給TabLayout添加Tab
        mTabLayout.addTab(mTabLayout.newTab().setText("新品"));
        mTabLayout.addTab(mTabLayout.newTab().setText("秒開"));
        mTabLayout.addTab(mTabLayout.newTab().setText("高價"));
        mTabLayout.addTab(mTabLayout.newTab().setText("低價"));
        mTabLayout.setupWithViewPager(mViewPager);//給TabLayout設置關聯ViewPager,如果設置了ViewPager,那麼ViewPagerAdapter中的getPageTitle()方法返回的就是Tab上的標題
    }

    private void initView() {
        vp_shuffling = (ViewPager) findViewById(R.id.vp_shuffling);
        // 廣告數據
        llIndexContainer = (LinearLayout)findViewById(R.id.ll_index_container);
        mADParseArray = new ArrayList<String>();
        mADParseArray
                .add("http://m.easyto.com/m/zhulifuwu_banner.jpg");
        mADParseArray
                .add("http://m.easyto.com/m/japan/images/banner_3y_new.jpg");
        mADParseArray
                .add("http://m.easyto.com/m/japan/images/banner_5y_new.jpg");
        vp_shuffling.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {

            @Override
            public void onPageSelected(int position) {
                refreshPoint(position % mADParseArray.size());
                if (mHandler.hasMessages(HOME_AD_RESULT)) {
                    mHandler.removeMessages(HOME_AD_RESULT);
                }
                mHandler.sendEmptyMessageDelayed(HOME_AD_RESULT, 3000);
            }

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

            @Override
            public void onPageScrollStateChanged(int arg0) {
                if (ViewPager.SCROLL_STATE_DRAGGING == arg0
                        && mHandler.hasMessages(HOME_AD_RESULT)) {
                    mHandler.removeMessages(HOME_AD_RESULT);
                }
            }
        });
        BannerAdapter adapter = new BannerAdapter(MainActivity.this, mADParseArray);
        vp_shuffling.setAdapter(adapter);
        addIndicatorImageViews(mADParseArray.size());
        vp_shuffling.setCurrentItem(mADParseArray.size() * 1000, false);
        // 自動輪播線程
        mHandler.sendEmptyMessageDelayed(HOME_AD_RESULT, 3000);
    }
    // 添加指示圖標
    private void addIndicatorImageViews(int size) {
        llIndexContainer.removeAllViews();
        for (int i = 0; i < size; i++) {
            ImageView iv = new ImageView(MainActivity.this);
            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(DensityUtil.dip2px(MainActivity.this, 5), DensityUtil.dip2px(MainActivity.this, 5));
            if (i != 0) {
                lp.leftMargin = DensityUtil.dip2px(MainActivity.this, 7);
            }
            iv.setLayoutParams(lp);
            iv.setBackgroundResource(R.drawable.xml_round_orange_grey_sel);
            iv.setEnabled(false);
            if (i == 0) {
                iv.setEnabled(true);
            }
            llIndexContainer.addView(iv);
        }
    }
    // 爲ViewPager設置監聽器
    private void refreshPoint(int position) {
        if (llIndexContainer != null) {
            for (int i = 0; i < llIndexContainer.getChildCount(); i++) {
                llIndexContainer.getChildAt(i).setEnabled(false);
                if (i == position) {
                    llIndexContainer.getChildAt(i).setEnabled(true);
                }
            }
        }
    }
}

主activity的佈局爲

<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/coordinator_layout"
    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:fitsSystemWindows="true">
        <RelativeLayout
            android:id="@+id/rel"
            app:layout_scrollFlags="scroll"
            android:layout_width="match_parent"
            android:layout_height="180dp">
            <android.support.v4.view.ViewPager
                android:background="#91deca"
                android:id="@+id/vp_shuffling"
                android:layout_width="match_parent"
                android:layout_height="match_parent"/>

            <LinearLayout
                android:id="@+id/ll_index_container"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:background="@drawable/home_banner_index_mask"
                android:gravity="center_horizontal"
                android:orientation="horizontal"
                android:paddingBottom="5dp"
                android:paddingTop="5dp"/>
        </RelativeLayout>
        <android.support.design.widget.TabLayout
            android:id="@+id/tabLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#91deca"
            app:tabGravity="fill"
            app:tabMode="fixed"
            app:tabSelectedTextColor="#ff0000"
            app:tabTextColor="#ffffff" />
    </android.support.design.widget.AppBarLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:scrollbars="none"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
        <android.support.v4.view.ViewPager
            android:id="@+id/viewpager"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </LinearLayout>

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

fragment的佈局爲

<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"
    >
   <android.support.v4.widget.SwipeRefreshLayout
       android:id="@+id/refresh_layout"
       android:layout_width="match_parent"
       android:layout_height="match_parent">
   <com.lyx.demo.view.LoadMoreRecyclerView
       android:id="@+id/recycler_view"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:scrollbars="none" />
</android.support.v4.widget.SwipeRefreshLayout>
</FrameLayout>

點擊去往csdn下載源碼

點擊去往github下載源碼

如有任何疑問歡迎留言

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章