- 内容簡介
- 實作步驟
- 第一步 找準方向
- 第二步 開幹
- 總結
- 還是題外話
内容簡介
簡單看一下需要實作的效果,如圖:
實作步驟
第一步 找準方向
其實就是想好要用recyclerview而不是listview。如果要問我recyclerview是什麼的話。。
第二步 開幹
首先需要先在xml裡放置這麼個控件
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/bg_main">
</android.support.v7.widget.RecyclerView>
這裡我加了一個背景,背景也可以在它的父布局加,主要是作為動畫的時候下面的顔色(顔色為一種灰色)。
然後,需要編寫每個item的布局,這裡也非常簡單,還是貼一下代碼:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="1dp"
android:background="@color/white"
android:orientation="horizontal">
<TextView
android:id="@+id/tv"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_weight="1"
android:gravity="center_vertical"
android:paddingLeft="5dp"
android:text="遼甯"
android:textColor="@android:color/black" />
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="center_vertical"
android:padding="3dp"
android:src="@mipmap/ic_right" />
</LinearLayout>
注意這裡的每個item的背景我都設定成了白色,這樣的話就能和背景色區分開。
接下來需要編寫adapter了,也就是recycler的adapter,這裡比較關鍵:
public class CheckProvAdapter extends RecyclerView.Adapter<CheckProvAdapter.CheckProvViewHolder> {
private Context context;
private int i = ;
public CheckProvAdapter(Context context) {
this.context = context;
}
@Override
public CheckProvViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = View.inflate(context,R.layout.item_check_prov,null);
v.setLayoutParams(new LinearLayoutCompat.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
CheckProvViewHolder viewHolder = new CheckProvViewHolder(v);
return viewHolder;
}
@Override
public void onBindViewHolder(CheckProvViewHolder holder, int position) {
if(position>i){
//上滑
ObjectAnimator.ofFloat(holder.itemView, "translationY", holder.itemView.getMeasuredHeight(), ).setDuration().start();
}else {
//下滑
}
i=position;
holder.tv.setText("遼甯");
}
@Override
public int getItemCount() {
return ;
}
public static class CheckProvViewHolder extends RecyclerView.ViewHolder {
TextView tv;
public CheckProvViewHolder(View itemView) {
super(itemView);
tv = (TextView) itemView.findViewById(R.id.tv);
}
}
}
關鍵部分為onBindViewHolder()這個方法,在這裡為itemview添加動畫并播放,這裡還有個小存在某種問題或陰謀,就是怎麼來判斷是向上滑還是向下滑呢,這裡我是根據position的增加或減少情況來判斷的,沒想到有什麼其他的更加完美的方法。
這樣,我們在上拉的時候來添加動畫并播放。adapter完成,接下來給recyclerview set上:
recyclerview = (RecyclerView) findViewById(R.id.recyclerview);
recyclerview.setLayoutManager(new LinearLayoutManager(this));
recyclerview.setAdapter(new CheckProvAdapter(this));
好的,這時候效果基本上已經出來了,但是還有點小瑕疵,因為沒有間距,說好的像listview一樣的間距呢,我表示不會,于是各種百度google,大神們說重寫ondraw方法就好了。我想了一下,我隻是要個間距而已,難道間距需要用畫的麼?于是我想了個可能是最簡單的recylerview加間距的方法:
public class LinearLayoutManagerDivider extends RecyclerView.ItemDecoration {
private int height;
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDraw(c,parent,state);
}
public LinearLayoutManagerDivider(int i) {
super();
height = i;//構造方法中傳入要設定的間距高度
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
outRect.set(,,,height);//最關鍵的一步,在這裡加間距,height為間距的高度
}
}
這個東西叫做RecyclerView.ItemDecoration,其中重寫的getItemOffsets看名字是來拿到item的偏移量的,因為如果畫了分隔線的話那item肯定會有偏移的嘛,如果我不畫分割線,隻偏移呢,那不就是傳說中的間距麼。。ok,就一句話:
然後給recycler放上呗:
recyclerview.addItemDecoration(new LinearLayoutManagerDivider(dp2px()));
recyclerview.setHasFixedSize(true);
因為我們是固定大小的,是以加上setHasFixedSize(true)這個方法來提高我們的效率。
好了到這裡所有的效果就已經實作了。
總結
兩個事,一動畫,二間距,動畫可以加在onBindViewHolder方法裡,而且動畫效果可以疊加;間距呢,剛才的方法outRect.set()方法,四個參數分别是left,top,right,bottom,不用我說這回也知道這個方法以後該怎麼了解了
還是題外話
以前一直沒有認真研究recyclerview,因為覺得listview已經很強大了,基本滿足工作中的所有需求了,而且看網上的部落格也好還是demo也好,總感覺這玩楞真複雜,太難了。但是咱要始終是要進步啊,是以就抽時間看了看官方文檔,發現也沒有自己想象中的那麼難,而且當初看到這個效果的時候首先想到的是在github上的一個庫,這裡的基本思路也是參考這個recyclerview-animators這個庫很友善,但是美中不足的是不能實作上圖中那種隻有上拉的時候有動畫,在下拉的時候沒有動畫,是以才有了小弟的這個方法。