利用RecyclerView實現(xiàn)自己的類似于ExpandableListView效果

關于RecyclerView總感覺有許多要說的牙勘,但是又不知道從什么地方說起周叮,今天這個不是我的第一篇關于RecyclerView上的文章,但是是我第一篇發(fā)表的宛渐,起個引子作用:
公司在項目中要實現(xiàn)一個類似于expandablelistview效果的控件竞漾,但是我已經(jīng)開始使用recyclerview,不想用listview窥翩,然后就走上了踩坑之路了业岁。

源碼地址
最開使用的是國外培訓機構(gòu)出品的一個控件,但是感覺很繁瑣寇蚊,實現(xiàn)起來有問題笔时,就自己重寫了一個實現(xiàn),這篇文章簡單的介紹代碼仗岸,沒有將原理允耿。

看一下效果圖:

上代碼:

1. 首先來看一下布局文件

fragment_history.xml

<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>

    </data>

    <LinearLayout xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context="com.saka.myapplication.Fragment.HistoryFragment">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="歷史上的今天"
            android:textSize="30sp" />
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text=""
            android:textSize="20sp"/>
        <android.support.v7.widget.RecyclerView
            android:id="@+id/rv_history"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>


    </LinearLayout>
</layout>

假如不熟悉Databinding的朋友可以去看看我的另一篇文章

DataBinding(一)-初識

布局文件很簡單,有用的只有這個recyclerview扒怖,其他的都沒用较锡。

2. 布局文件的java代碼

這里是一些常規(guī)化的代碼。

 /**
     * 初始化RecyclerView
     */
    private void initViews() {
        binding.rvHistory.setLayoutManager(new LinearLayoutManager(getActivity()));
        binding.rvHistory.setItemAnimator(new NoAlphaItemAnimator());
        adapter = new HistoryAdapter(getActivity(), results);
        adapter.setItemClickListener(this);
        binding.rvHistory.setAdapter(adapter);
        startRequest();
    }

首先是setlayoutManager盗痒,此處我用的是垂直的布局蚂蕴。

然后是setItemAnimator,這個是重點俯邓,同學們要好好記骡楼。

然后是adapter,這個是實現(xiàn)的具體方法看成。一會重點講君编。

startrequest是請求數(shù)據(jù)的方法,用來更新數(shù)據(jù)川慌。

3. 看一下item的布局文件(稍微復雜)

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

    <data>

        <variable
            name="historymodel"
            type="com.saka.myapplication.Models.HistoryModle.HistoryResult" />
    <variable
        name="historyclickevent"
        type="com.saka.myapplication.Models.SearchItemClick"/>
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/colorPrimary"
            android:gravity="center"
            android:paddingBottom="10dp"
            android:onClick="@{()->historyclickevent.onClickItem()}"
            android:text="@{historymodel.title}"
            android:textColor="@color/textwhite"
            android:textSize="20sp" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:visibility="@{historymodel.showDetails}">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal">

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="時間:"
                    android:textColor="@color/colorAccent"
                    android:textSize="15sp" />

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="@{historymodel.date}"
                    android:textSize="15sp" />
            </LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal">

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="農(nóng)歷:"
                    android:textColor="@color/colorAccent"
                    android:textSize="15sp" />

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="@{historymodel.lunnar}"
                    android:textSize="15sp" />
            </LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal">

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="事件:"
                    android:textColor="@color/colorAccent"
                    android:textSize="15sp" />

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@{historymodel.des}"
                    android:textSize="15sp" />
                    
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>
</layout>

生成的布局文件大概是這樣的:

共包含三個部分吃嘿,首先是標題部分,就是那個淺藍色梦重,雖然沒什么內(nèi)容都沒有兑燥,但是請求到內(nèi)容后就會顯示文字了。

下面部分 時間琴拧、農(nóng)歷降瞳、事件 是需要隱藏的部分。

4 HistoryHolder內(nèi)容

此處要注意databing的寫法。上邊的鏈接有詳細介紹

static class HistoryHolder extends RecyclerView.ViewHolder {
        ViewDataBinding binding;
        public HistoryHolder(ViewDataBinding binding) {
            super(binding.getRoot());
            this.binding = binding;
        }

        static HistoryHolder createViewHolder(ViewGroup container, int layoutId) {
            ViewDataBinding binding = DataBindingUtil.inflate(
                    LayoutInflater.from(container.getContext()), layoutId, container, false);
            return new HistoryHolder(binding);
        }
    }

這個viewholer是一個通用的holder挣饥,是傳參數(shù)傳進來item布局文件的id int layoutId除师;

5. HistoryAdapter文件

關于adapter要復寫的幾個方法主要講這個onBindViewHoler方法:

 @Override
    public void onBindViewHolder(HistoryHolder holder, int position) {
        holder.binding.setVariable(BR.historymodel, historyResults[position]);
        searchItemClick=new SearchItemClick(position);
        searchItemClick.setListener(listener);
        holder.binding.setVariable(BR.historyclickevent,searchItemClick);
        holder.binding.executePendingBindings();

    }

這個地方的historymodel對應item布局文件中的variable中的
name="historymodel" type="com.saka.myapplication.Models.HistoryModle.HistoryResult" />

這個searchItemClick是一個點擊事件,用來傳遞position參數(shù)

在Historyfragment實現(xiàn)了這個接口扔枫,用來隱藏/顯示detail(詳細內(nèi)容)汛聚。

 @Override
    public void onItemClick(int resId) {
        Log.d("fff", "點擊了事件" + resId);
        if (results[resId].getShowDetails() == View.GONE) {
            Log.d("fff", "顯示條目");
            results[resId].setShowDetails(View.VISIBLE);
        } else {
            Log.d("fff", "隱藏條目");
            results[resId].setShowDetails(View.GONE);
        }
        adapter.notifyItemChanged(resId);
    }

此時打開應用可以看到這個時候已經(jīng)可以簡單的擴展收縮了

但是看清楚,在現(xiàn)實detail的時候效果還可以短荐,但是隱藏detail的時候就非常蛋疼了倚舀,是下邊的item完全上去之后detail的內(nèi)容才會隱藏,這就很難受了忍宋。

這個時候要研究一下recyclerview的動畫機制痕貌。在你不給recyclerview添加動畫時,adapter.notifyItemChanged()方法會出發(fā)recyclerview的動畫糠排,一般有個默認的DefaultItemAnimator()動畫舵稠。我們要做的就是重寫這類,做成我們想要的動畫效果乳讥。

我新建了一個動畫類叫NoAlphaItemAnimator柱查,此處我要實現(xiàn)的是在點擊后改變item的高度,而不是刪除或者添加云石,我們需要找到這個內(nèi)部類唉工,private static class ChangeInfo。
它就是在改變item時調(diào)用的動畫汹忠,然后找到void animateChangeImpl(final ChangeInfo changeInfo)這個方法淋硝,找到里邊的實現(xiàn)方法 public void onAnimationStart(View view)
在下邊添加

 if (view.findViewById(history_more).getVisibility() == View.GONE) {
                        AlphaAnimation animation = new AlphaAnimation(0, 1);
                        animation.setDuration(300);
                        view.findViewById(history_more).startAnimation(animation);
                    } else {
                        AlphaAnimation alphaAnimation = new AlphaAnimation(1, 0);
                        alphaAnimation.setDuration(300);
                        view.findViewById(history_more).startAnimation(alphaAnimation);
                        view.findViewById(history_more).setVisibility(View.GONE);
                    }

添加如上代碼,就可以實現(xiàn)隱藏了宽菜。
看一下效果:


最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末谣膳,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子铅乡,更是在濱河造成了極大的恐慌继谚,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件阵幸,死亡現(xiàn)場離奇詭異花履,居然都是意外死亡,警方通過查閱死者的電腦和手機挚赊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門诡壁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人荠割,你說我怎么就攤上這事妹卿。” “怎么了?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵夺克,是天一觀的道長箕宙。 經(jīng)常有香客問我,道長铺纽,這世上最難降的妖魔是什么扒吁? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮室囊,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘魁索。我一直安慰自己融撞,他們只是感情好,可當我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布粗蔚。 她就那樣靜靜地躺著尝偎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鹏控。 梳的紋絲不亂的頭發(fā)上致扯,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天,我揣著相機與錄音当辐,去河邊找鬼抖僵。 笑死,一個胖子當著我的面吹牛缘揪,可吹牛的內(nèi)容都是我干的耍群。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼找筝,長吁一口氣:“原來是場噩夢啊……” “哼蹈垢!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起袖裕,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤曹抬,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后急鳄,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體谤民,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年攒岛,在試婚紗的時候發(fā)現(xiàn)自己被綠了赖临。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡灾锯,死狀恐怖兢榨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤吵聪,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布凌那,位于F島的核電站,受9級特大地震影響吟逝,放射性物質(zhì)發(fā)生泄漏帽蝶。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一块攒、第九天 我趴在偏房一處隱蔽的房頂上張望励稳。 院中可真熱鬧,春花似錦囱井、人聲如沸驹尼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽新翎。三九已至,卻和暖如春住练,著一層夾襖步出監(jiān)牢的瞬間地啰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工讲逛, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留亏吝,地道東北人。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓盏混,卻偏偏與公主長得像顺呕,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子括饶,可洞房花燭夜當晚...
    茶點故事閱讀 42,802評論 2 345

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