Android開發(fā)之RecyclView

筆者在刷知乎的時(shí)候看到不要再用ListView了替蔬,改用RecyclerView吧坯辩!作為一個(gè)重癥知乎迷覆履,當(dāng)然要去have a look究恤,那么今天我們一起see see吧俭令。

據(jù)官方介紹RecyclerViewListView的升級(jí)版,既然是升級(jí)版部宿,肯定具有更多的優(yōu)點(diǎn)抄腔,那么我們來看看RecyclerView有哪些優(yōu)點(diǎn):

  1. RecylerView封裝了viewholder的回收復(fù)用,也就是說RecylerView標(biāo)準(zhǔn)化了ViewHolder理张,編寫Adapter面向的是ViewHolder而不再是View了赫蛇,復(fù)用的邏輯被封裝了,寫起來更加簡(jiǎn)單雾叭。
  2. 提供了一種插拔式的體驗(yàn)悟耘,高度的解耦,異常的靈活织狐,針對(duì)一個(gè)Item的顯示RecylerView專門抽取出了相應(yīng)的類暂幼,來控制Item的顯示筏勒,使其的擴(kuò)展性非常強(qiáng)。例如:你想控制橫向或者縱向滑動(dòng)列表效果可以通過LinearLayoutManager這個(gè)類來進(jìn)行控制(與GridView效果對(duì)應(yīng)的是GridLayoutManager,與瀑布流對(duì)應(yīng)的還有StaggeredGridLayoutManager等)旺嬉,也就是說RecylerView不再拘泥于ListView的線性展示方式管行,它也可以實(shí)現(xiàn)GridView的效果等多種效果。你想控制Item的分隔線鹰服,可以通過繼承RecylerView的ItemDecoration這個(gè)類病瞳,然后針對(duì)自己的業(yè)務(wù)需求去抒寫代碼揽咕。
  3. 可以控制Item增刪的動(dòng)畫悲酷,可以通過ItemAnimator這個(gè)類進(jìn)行控制,當(dāng)然針對(duì)增刪的動(dòng)畫亲善,RecylerView有其自己默認(rèn)的實(shí)現(xiàn)设易。

下面來介紹RecyclerView的用法。

首先首先要用這個(gè)控件蛹头,你需要在gradle文件中添加包的引用(配合官方CardView使用)

compile 'com.android.support:cardview-v7:21.0.3' compile 'com.android.support:recyclerview-v7:21.0.3'

然后在XML布局文件里使用

<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/recycler_view" android:layout_centerVertical="true" android:layout_centerHorizontal="true"/>

再接著是activity

mRecyclerView = findView(R.id.id_recyclerview); //設(shè)置布局管理器 mRecyclerView.setLayoutManager(layout); //設(shè)置adapter mRecyclerView.setAdapter(adapter) //設(shè)置Item增加顿肺、移除動(dòng)畫 mRecyclerView.setItemAnimator(new DefaultItemAnimator()); //添加分割線 mRecyclerView.addItemDecoration(new DividerItemDecoration( getActivity(), DividerItemDecoration.HORIZONTAL_LIST));
在這里我們看到設(shè)置過程比ListView復(fù)雜一些,這是RecyclerView高度解耦的表現(xiàn)渣蜗,擴(kuò)展性極強(qiáng)屠尊。

下面是顯示A-Z的RecyclerView的實(shí)現(xiàn)
Activity

public class HomeActivity extends ActionBarActivity {

private RecyclerView mRecyclerView;
private List<String> mDatas;
private HomeAdapter mAdapter;

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

    initData();
    mRecyclerView = (RecyclerView) findViewById(R.id.id_recyclerview);
    mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
    mRecyclerView.setAdapter(mAdapter = new HomeAdapter());

}

protected void initData()
{
    mDatas = new ArrayList<String>();
    for (int i = 'A'; i < 'z'; i++)
    {
        mDatas.add("" + (char) i);
    }
}

class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.MyViewHolder>
{

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
    {
        MyViewHolder holder = new MyViewHolder(LayoutInflater.from(
                HomeActivity.this).inflate(R.layout.item_home, parent,
                false));
        return holder;
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position)
    {
        holder.tv.setText(mDatas.get(position));
    }

    @Override
    public int getItemCount()
    {
        return mDatas.size();
    }

    class MyViewHolder extends ViewHolder
    {

        TextView tv;

        public MyViewHolder(View view)
        {
            super(view);
            tv = (TextView) view.findViewById(R.id.id_num);
        }
    }
}

}
這個(gè)實(shí)際效果item間是沒有分割線的

Paste_Image.png

下面添加分割線

mRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST));
該方法會(huì)調(diào)用系統(tǒng)默認(rèn)的分割線

Paste_Image.png

系統(tǒng)分割線可以在theme.xml里找到
<style name="AppTheme" parent="AppBaseTheme"> <item name="android:listDivider">@drawable/divider_bg</item> </style>
當(dāng)然我們可以自己實(shí)現(xiàn)個(gè)drawable
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >

`<gradient
    android:centerColor="#ff00ff00"
    android:endColor="#ff0000ff"
    android:startColor="#ffff0000"
    android:type="linear" />
<size android:height="4dp"/>`

</shape>

v
線性布局我們就說到這,下面實(shí)現(xiàn)瀑布流布局

mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(4, StaggeredGridLayoutManager.VERTICAL));
只需要一行耕拷,注意StaggeredGridLayoutManager構(gòu)造的第二個(gè)參數(shù)傳一個(gè)orientation讼昆,如果傳入的是StaggeredGridLayoutManager.VERTICAL代表有多少列;那么傳入的如果是StaggeredGridLayoutManager.HORIZONTAL就代表有多少行骚烧。假如上面代碼改為:
mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(4, StaggeredGridLayoutManager.HORIZONTAL));
效果為:

Paste_Image.png

這個(gè)效果顯然不夠驚艷浸赫,下面我們?cè)谶m配器的onBindViewHolder方法中為item設(shè)置個(gè)隨機(jī)高度,即可實(shí)現(xiàn)以下效果:


Paste_Image.png

更驚艷的地方是item增加赃绊、刪除的動(dòng)畫也是可配置的既峡。接下來看一下ItemAnimator。

ItemAnimator

使用默認(rèn)的效果也只需要一行代碼:
// 設(shè)置item動(dòng)畫 mRecyclerView.setItemAnimator(new DefaultItemAnimator());
效果:

20150415194114149.gif
]
有個(gè)令人頭疼的地方是系統(tǒng)沒有提供ClickListener和LongClickListener碧查,所以我們只能自己去實(shí)現(xiàn)运敢。
class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.MyViewHolder> {

public interface OnItemClickLitener
{
    void onItemClick(View view, int position);
    void onItemLongClick(View view , int position);
}

private OnItemClickLitener mOnItemClickLitener;

public void setOnItemClickLitener(OnItemClickLitener mOnItemClickLitener)
{
    this.mOnItemClickLitener = mOnItemClickLitener;
}

@Override
public void onBindViewHolder(final MyViewHolder holder, final int position)
{
    holder.tv.setText(mDatas.get(position));

    // 如果設(shè)置了回調(diào),則設(shè)置點(diǎn)擊事件
    if (mOnItemClickLitener != null)
    {
        holder.itemView.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                int pos = holder.getLayoutPosition();
                mOnItemClickLitener.onItemClick(holder.itemView, pos);
            }
        });

        holder.itemView.setOnLongClickListener(new OnLongClickListener()
        {
            @Override
            public boolean onLongClick(View v)
            {
                int pos = holder.getLayoutPosition();
                mOnItemClickLitener.onItemLongClick(holder.itemView, pos);
                return false;
            }
        });
    }
}

}
Activity設(shè)置監(jiān)聽:
mAdapter.setOnItemClickLitener(new OnItemClickLitener() {

        @Override
        public void onItemClick(View view, int position)
        {
            Toast.makeText(HomeActivity.this, position + " click",
                    Toast.LENGTH_SHORT).show();
        }

       @Override
        public void onItemLongClick(View view, int position)
        {
            Toast.makeText(HomeActivity.this, position + " long click",
                    Toast.LENGTH_SHORT).show();
                    mAdapter.removeData(position);
        }
    });

別忘了給item添加一個(gè)drawable:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" > <item android:state_pressed="true" android:drawable="@color/color_item_press"></item> <item android:drawable="@color/color_item_normal"></item> </selector>
效果:

20150415194800546.gif

源碼下載:源碼下載

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末忠售,一起剝皮案震驚了整個(gè)濱河市传惠,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌档痪,老刑警劉巖涉枫,帶你破解...
    沈念sama閱讀 222,590評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異腐螟,居然都是意外死亡愿汰,警方通過查閱死者的電腦和手機(jī)困后,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來衬廷,“玉大人摇予,你說我怎么就攤上這事÷鸢希” “怎么了侧戴?”我有些...
    開封第一講書人閱讀 169,301評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)跌宛。 經(jīng)常有香客問我酗宋,道長(zhǎng),這世上最難降的妖魔是什么疆拘? 我笑而不...
    開封第一講書人閱讀 60,078評(píng)論 1 300
  • 正文 為了忘掉前任蜕猫,我火速辦了婚禮,結(jié)果婚禮上哎迄,老公的妹妹穿的比我還像新娘回右。我一直安慰自己,他們只是感情好漱挚,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,082評(píng)論 6 398
  • 文/花漫 我一把揭開白布翔烁。 她就那樣靜靜地躺著,像睡著了一般旨涝。 火紅的嫁衣襯著肌膚如雪蹬屹。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,682評(píng)論 1 312
  • 那天颊糜,我揣著相機(jī)與錄音哩治,去河邊找鬼。 笑死衬鱼,一個(gè)胖子當(dāng)著我的面吹牛业筏,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播鸟赫,決...
    沈念sama閱讀 41,155評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼蒜胖,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了抛蚤?” 一聲冷哼從身側(cè)響起台谢,我...
    開封第一講書人閱讀 40,098評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎岁经,沒想到半個(gè)月后朋沮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,638評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡缀壤,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,701評(píng)論 3 342
  • 正文 我和宋清朗相戀三年樊拓,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了纠亚。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,852評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡筋夏,死狀恐怖蒂胞,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情条篷,我是刑警寧澤骗随,帶...
    沈念sama閱讀 36,520評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站赴叹,受9級(jí)特大地震影響鸿染,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜稚瘾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,181評(píng)論 3 335
  • 文/蒙蒙 一牡昆、第九天 我趴在偏房一處隱蔽的房頂上張望姚炕。 院中可真熱鬧摊欠,春花似錦、人聲如沸柱宦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽掸刊。三九已至免糕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間忧侧,已是汗流浹背石窑。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蚓炬,地道東北人松逊。 一個(gè)月前我還...
    沈念sama閱讀 49,279評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像肯夏,于是被迫代替她去往敵國(guó)和親经宏。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,851評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • 自Android 5.0之后驯击,谷歌公司推出了RecylerView控件烁兰,RecylerView,我想看到一個(gè)新名詞...
    苦可樂閱讀 2,319評(píng)論 0 5
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,321評(píng)論 25 707
  • 陳小米 第十一章 反了 一夜混亂。雖然巨巖哥哥讓我睡覺徊都,可我興奮的睡不著沪斟。大叔帶著哥哥他們?nèi)プノ鍫斄耍劣谙窘茫麄?..
    小米rt8閱讀 237評(píng)論 2 2
  • 一直知道女人喝點(diǎn)糯米酒有好處主之,上次小陶也跟我說過自己可以做轨域,還把做法告訴了我,可我一轉(zhuǎn)眼就不記得了杀餐,還是覺...
    國(guó)國(guó)2580閱讀 301評(píng)論 0 0