簡單實現仿某寶地址選擇三級聯動樣式
- 內容簡單介紹
- 實現步驟
- 第一步 找準方向
- 第二步 開幹
- 總結
- 還是題外話
內容簡單介紹
簡單看一下須要實現的效果,如圖:
實現步驟
第一步 找準方向
事實上就是想好要用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的布局,這裏也非常easy,還是貼一下代碼:
<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 = 0;
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(), 0).setDuration(300).start();
}else {
//下滑
}
i=position;
holder.tv.setText("遼寧");
}
@Override
public int getItemCount() {
return 100;
}
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(0,0,0,height);//最關鍵的一步。在這裏加間距。height為間距的高度
}
}
這個東西叫做RecyclerView.ItemDecoration,當中重寫的getItemOffsets看名字是來拿到item的偏移量的,由於假設畫了分隔線的話那item肯定會有偏移的嘛,假設我不畫切割線,僅僅偏移呢。那不就是傳說中的間距麽。
。
ok,就一句話:
outRect.set(0,0,0,height);
然後給recycler放上唄:
recyclerview.addItemDecoration(new LinearLayoutManagerDivider(dp2px(1)));
recyclerview.setHasFixedSize(true);
由於我們是固定大小的,所以加上setHasFixedSize(true)這種方法來提高我們的效率。
好了到這裏全部的效果就已經實現了。
總結
兩個事,一動畫。二間距。動畫能夠加在onBindViewHolder方法裏,並且動畫效果能夠疊加。間距呢,剛才的方法outRect.set()方法。四個參數各自是left。top。right,bottom,不用我說這回也知道這種方法以後該怎麽理解了
還是題外話
曾經一直沒有認真研究recyclerview,由於認為listview已經非常強大了。基本滿足工作中的全部需求了,並且看網上的博客也好還是demo也好,總感覺這玩楞真復雜。太難了。可是咱要始終是要進步啊,所以就抽時間看了看官方文檔,發現也沒有自己想象中的那麽難。並且當初看到這個效果的時候首先想到的是在github上的一個庫,這裏的基本思路也是參考這個recyclerview-animators這個庫非常方便。可是美中不足的是不能實現上圖中那種僅僅有上拉的時候有動畫,在下拉的時候沒有動畫,所以才有了小弟的這種方法。
簡單實現仿某寶地址選擇三級聯動樣式