Android5.0新控件RecyclerVIew的介紹和兼容使用的方法

  第一部分html

  RecyclerVIew是一個能夠替代listview和Gallery的有效空間並且在support-v7中有了低版本支持,具體使用方式仍是規規矩矩的適配器加控件模式。咱們先來看看官網的介紹:android

介紹

RecyclerView  is a more advanced and flexible version of  ListView . This widget is a container for large sets of views that can be recycled and scrolled very efficiently. Use the  RecyclerView  widget when you have lists with elements that change dynamically.ios

RecyclerView比listview更先進更靈活,對於不少的視圖它就是一個容器,能夠有效的重用和滾動。當數據動態變化的時候請使用它。app

 

RecyclerView  is easy to use, because it provides:ide

  • A layout manager for positioning items
  • Default animations for common item operations
  • You also have the flexibility to define custom layout managers and animations for this widget.

RecyclerView使用起來很方便由於它提供:佈局

  • 它爲item的定位提供一個layoutmanager
  • 爲item的操做提供一個缺省的animations
  • 您還能夠靈活地定義這個小部件的自定義佈局管理器動畫

 

To use the  RecyclerView  widget, you have to specify an adapter and a layout manager. To create an adapter, you extend the  RecyclerView.Adapter  class. The details of the implementation depend on the specifics of your dataset and the type of views. For more information, see the  examplesbelow.性能

爲了使用RecyclerVIew,你必須指定一個adapter和一個layoutmanager,爲了建立一個adapter,你必須得繼承RecyclerView.Adapter,詳細的實現方法取決與你的數據集和你視圖的類型。flex

 

Google官方的一個例子:優化

1.佈局文件activity_main.xml動畫

<RelativeLayout 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="${relativePackage}.${activityClass}" >

    <!-- A RecyclerView with some commonly used attributes -->

    <android.support.v7.widget.RecyclerView
        android:id="@+id/my_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="horizontal" 
        />

</RelativeLayout>

 

2.item的佈局文件,就是一個textview

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:text="Large Text"
    android:textAppearance="?android:attr/textAppearanceLarge" />

 

3.主要代碼

3.1 定義控件和佈局

  /* 
     * recyclerview提供這些內置的佈局管理器:  
     * linearlayoutmanager              顯示垂直滾動列表或水平的項目。 
     * gridlayoutmanager                顯示在一個網格項目。  
     * staggeredgridlayoutmanager       顯示在交錯網格項目。 
     * 自定義的佈局管理器,須要繼承recyclerview.layoutmanager類。 
     *  
     * add/remove items時的動畫是默認啓用的。 
     * 自定義這些動畫須要繼承RecyclerView.ItemAnimator,並實現RecyclerView.setItemAnimator() 
     */  
    private RecyclerView mRecyclerView;
    private RecyclerView.Adapter<MyAdapter.ViewHolder> mAdapter;
    private LinearLayoutManager mLayoutManager;  

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        String [] myDataset = {"Android","ios","jack","tony","window","mac","1234","hehe","495948"};

        mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);

        // improve performance if you know that changes in content
        // do not change the size of the RecyclerView
        mRecyclerView.setHasFixedSize(true);

        // use a linear layout manager
        mLayoutManager = new LinearLayoutManager(this);
        //設置RecycleView的顯示方向:(默認爲垂直) 水平
        mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        mRecyclerView.setLayoutManager(mLayoutManager);

        // specify an adapter (see also next example)
        mAdapter = new MyAdapter(myDataset);
        mRecyclerView.setAdapter(mAdapter);
    }

3.2 適配器

    public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
        private String[] mDataset;

        // Provide a reference to the type of views that you are using
        // (custom viewholder)
        public class ViewHolder extends RecyclerView.ViewHolder {
            public TextView mTextView;

            public ViewHolder(TextView v) {
                super(v);
                mTextView = v;
            }
        }

        // Provide a suitable constructor (depends on the kind of dataset)
        public MyAdapter(String[] myDataset) {
            mDataset = myDataset;
        }

        // Create new views (invoked by the layout manager)
        @Override
        public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                int viewType) {
            // create a new view
            View v = LayoutInflater.from(parent.getContext()).inflate(
                    R.layout.my_text_view, parent, false);
            // set the view's size, margins, paddings and layout parameters

            ViewHolder vh = new ViewHolder((TextView) v);
            return vh;
        }

        // Replace the contents of a view (invoked by the layout manager)
        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            // - get element from your dataset at this position
            // - replace the contents of the view with that element
            holder.mTextView.setText(mDataset[position]);

        }

        // Return the size of your dataset (invoked by the layout manager)
        @Override
        public int getItemCount() {
            return mDataset.length;
        }
    }

 

所有代碼:

package com.kale.recyclerviewtest;

import android.app.Activity;
import android.os.Bundle;
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 android.widget.TextView;

public class MainActivity extends Activity {

    private RecyclerView mRecyclerView;
    private RecyclerView.Adapter<MyAdapter.ViewHolder> mAdapter;
    private LinearLayoutManager mLayoutManager;  

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        String [] myDataset = {"Android","ios","jack","tony","window","mac","1234","hehe","495948"};

        mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);

        // improve performance if you know that changes in content
        // do not change the size of the RecyclerView
        mRecyclerView.setHasFixedSize(true);

        // use a linear layout manager
        mLayoutManager = new LinearLayoutManager(this);
        //設置RecycleView的顯示方向:(默認爲垂直) 水平
        mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        mRecyclerView.setLayoutManager(mLayoutManager);

        // specify an adapter (see also next example)
        mAdapter = new MyAdapter(myDataset);
        mRecyclerView.setAdapter(mAdapter);
    }

    public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
        private String[] mDataset;

        // Provide a reference to the type of views that you are using
        // (custom viewholder)
        public class ViewHolder extends RecyclerView.ViewHolder {
            public TextView mTextView;

            public ViewHolder(TextView v) {
                super(v);
                mTextView = v;
            }
        }

        // Provide a suitable constructor (depends on the kind of dataset)
        public MyAdapter(String[] myDataset) {
            mDataset = myDataset;
        }

        // Create new views (invoked by the layout manager)
        @Override
        public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                int viewType) {
            // create a new view
            View v = LayoutInflater.from(parent.getContext()).inflate(
                    R.layout.my_text_view, parent, false);
            // set the view's size, margins, paddings and layout parameters

            ViewHolder vh = new ViewHolder((TextView) v);
            return vh;
        }

        // Replace the contents of a view (invoked by the layout manager)
        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            // - get element from your dataset at this position
            // - replace the contents of the view with that element
            holder.mTextView.setText(mDataset[position]);

        }

        // Return the size of your dataset (invoked by the layout manager)
        @Override
        public int getItemCount() {
            return mDataset.length;
        }
    }
}

 

PS:這個控件好就好在能夠自定義動畫和佈局的方向,在之前還須要咱們本身寫橫向滑動的listview,如今有了它就方便多了。但缺點是沒有listview那麼完善,沒添加頭、尾視圖的功能。再說下它的動畫和佈局類,之後用到的話就知道了。

(1)爲每一個條目位置提供了layout管理器(RecyclerView.setLayoutManager

(2)爲每一個條目設置了操做動畫(RecyclerView.setItemAnimator

 

第二部分

  如今咱們知道它是什麼,怎麼用了後。咱們就想本身實現點擊效果,要知道它是不提供itemclicklistner的,因此須要換個思路,在viewHolder中進行實現。其實這樣的分離讓代碼更加簡單和便於維護了。下面的代碼僅僅是概要演示,具體實際操做中咱們徹底能夠利用viewholder來提高滑動的性能,若是viewHolder 中有這個視圖那麼就調出,若是沒有那麼就從新findviewById。

1.viewHolder

viewholder中傳入了一個父視圖,直接綁定監聽器。而後根據須要找到子視圖,進行操做。

    
    /**
     * @author:Jack Tony
     * @tips  :寫一個viewHolder,用來獲得控件。
     * @date  :2014-11-1
     */
    public class MyViewHolder extends RecyclerView.ViewHolder implements OnClickListener,OnLongClickListener{
        
        private TextView mTextView;  
        private int mPosition;
        
        public MyViewHolder(View rootView) {
            super(rootView);
            //給父控件綁定監聽器
            rootView.setOnClickListener(this);
            //經過findviewbyId找到item中的控件進行設置
            mTextView = (TextView)rootView.findViewById(R.id.textView1);
            ImageView imageView = (ImageView)rootView.findViewById(R.id.imageView1);
            imageView.setImageResource(R.drawable.kale);
        }
        
        public void setPosition(int position) {
            mPosition = position;
        }

        @Override
        public boolean onLongClick(View v) {
            // TODO 自動生成的方法存根
            return false;
        }

        @Override
        public void onClick(View v) {
            // TODO 自動生成的方法存根
            Toast.makeText(MainActivity.this, "click "+mPosition, 0).show();
        }  
        
    }

 

2.Adapter

由於用了本身寫的MyHolder,因此這裏類的泛型中應該傳入本身的這個viewHolder的類名。具體寫法仍是和第一部分中的寫法同樣,甚至簡單了不少。由於這裏咱們只須要關係數據源和位置便可。

    /**
     * @author:Jack Tony
     * @tips  :這裏面徹底能夠根據viewholder是否爲null進行優化
     * @date  :2014-11-1
     */
    public class Adapter extends RecyclerView.Adapter<MyViewHolder>{

        private String[] mDataset;
        private MyViewHolder mViewHoder;
        
        public Adapter(String[] myDataset) {
            mDataset = myDataset;
        }
        
        @Override
        public int getItemCount() {
            // TODO 自動生成的方法存根
            return mDataset.length;
        }

        @Override
        public void onBindViewHolder(MyViewHolder holder, int position) {
            mViewHoder.mTextView.setText(mDataset[position]);
            mViewHoder.setPosition(position);
        }

        @Override
        public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
             mViewHoder = new MyViewHolder(v);
            return mViewHoder;
        }
        
    }
    

 

3.Animation

經過繼承RecyclerView.ItemAnimator這個類就能夠給RecylerView添加item動畫,至於具體的實現網上沒有什麼資料。因此我這裏也沒想出怎麼玩的,之後再補上吧。這裏先給出空實現。

    public class MyAnim extends RecyclerView.ItemAnimator{

        @Override
        public boolean animateAdd(ViewHolder arg0) {
            // TODO 自動生成的方法存根
            return false;
        }

        @Override
        public boolean animateChange(ViewHolder arg0, ViewHolder arg1,
                int arg2, int arg3, int arg4, int arg5) {
            // TODO 自動生成的方法存根
            return false;
        }

        @Override
        public boolean animateMove(ViewHolder holder, int fromX, int fromY, int toX, int toY) {
            // TODO 自動生成的方法存根
            return false;
        }

        @Override
        public boolean animateRemove(ViewHolder arg0) {
            // TODO 自動生成的方法存根
            return false;
        }

        @Override
        public void endAnimation(ViewHolder arg0) {
            // TODO 自動生成的方法存根
            
        }

        @Override
        public void endAnimations() {
            // TODO 自動生成的方法存根
            
        }

        @Override
        public boolean isRunning() {
            // TODO 自動生成的方法存根
            return false;
        }

        @Override
        public void runPendingAnimations() {
            // TODO 自動生成的方法存根
            
        }
        
    }
mRecyclerView.setItemAnimator(new MyAnim());

 

所有代碼:

package com.kale.recyclerviewtest;

import android.app.Activity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;


public class MainActivity extends Activity {

    private RecyclerView mRecyclerView;
    private Adapter mAdapter;
    private LinearLayoutManager mLayoutManager;  

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        String [] myDataset = {"Android","ios","jack","tony","window","mac","C#","hehe","C++"};

        mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);

        // improve performance if you know that changes in content
        // do not change the size of the RecyclerView
        mRecyclerView.setHasFixedSize(true);

        // use a linear layout manager
        mLayoutManager = new LinearLayoutManager(this);
        //設置RecycleView的顯示方向:(默認爲垂直) 水平
        mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        mRecyclerView.setLayoutManager(mLayoutManager);

        // specify an adapter (see also next example)
        mAdapter = new Adapter(myDataset);
        mRecyclerView.setAdapter(mAdapter);
        mRecyclerView.setItemAnimator(new MyAnim());
    }
    
    
    
    /**
     * @author:Jack Tony
     * @tips  :寫一個viewHolder,用來獲得控件。
     * @date  :2014-11-1
     */
    public class MyViewHolder extends RecyclerView.ViewHolder implements OnClickListener,OnLongClickListener{
        
        private TextView mTextView;  
        private int mPosition;
        
        public MyViewHolder(View rootView) {
            super(rootView);
            //給父控件綁定監聽器
            rootView.setOnClickListener(this);
            //經過findviewbyId找到item中的控件進行設置
            mTextView = (TextView)rootView.findViewById(R.id.textView1);
            ImageView imageView = (ImageView)rootView.findViewById(R.id.imageView1);
            imageView.setImageResource(R.drawable.kale);
        }
        
        public void setPosition(int position) {
            mPosition = position;
        }

        @Override
        public boolean onLongClick(View v) {
            // TODO 自動生成的方法存根
            return false;
        }

        @Override
        public void onClick(View v) {
            // TODO 自動生成的方法存根
            Toast.makeText(MainActivity.this, "click "+mPosition, 0).show();
        }  
        
    }
    
    /**
     * @author:Jack Tony
     * @tips  :這裏面徹底能夠根據viewholder是否爲null進行優化
     * @date  :2014-11-1
     */
    public class Adapter extends RecyclerView.Adapter<MyViewHolder>{

        private String[] mDataset;
        private MyViewHolder mViewHoder;
        
        public Adapter(String[] myDataset) {
            mDataset = myDataset;
        }
        
        @Override
        public int getItemCount() {
            // TODO 自動生成的方法存根
            return mDataset.length;
        }

        @Override
        public void onBindViewHolder(MyViewHolder holder, int position) {
            mViewHoder.mTextView.setText(mDataset[position]);
            mViewHoder.setPosition(position);
        }

        @Override
        public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
             mViewHoder = new MyViewHolder(v);
            return mViewHoder;
        }
        
    }
    
    public class MyAnim extends RecyclerView.ItemAnimator{

        @Override
        public boolean animateAdd(ViewHolder arg0) {
            // TODO 自動生成的方法存根
            return false;
        }

        @Override
        public boolean animateChange(ViewHolder arg0, ViewHolder arg1,
                int arg2, int arg3, int arg4, int arg5) {
            // TODO 自動生成的方法存根
            return false;
        }

        @Override
        public boolean animateMove(ViewHolder holder, int fromX, int fromY, int toX, int toY) {
            // TODO 自動生成的方法存根
            return false;
        }

        @Override
        public boolean animateRemove(ViewHolder arg0) {
            // TODO 自動生成的方法存根
            return false;
        }

        @Override
        public void endAnimation(ViewHolder arg0) {
            // TODO 自動生成的方法存根
            
        }

        @Override
        public void endAnimations() {
            // TODO 自動生成的方法存根
            
        }

        @Override
        public boolean isRunning() {
            // TODO 自動生成的方法存根
            return false;
        }

        @Override
        public void runPendingAnimations() {
            // TODO 自動生成的方法存根
            
        }
        
    }
    



}

 

源碼下載:http://download.csdn.net/detail/shark0017/8110309

 

參考自:

http://blog.csdn.net/jjwwmlp456/article/details/40540233

http://blog.csdn.net/a396901990/article/details/40187769

http://blog.csdn.net/guxiao1201/article/details/40423361

相關文章
相關標籤/搜索