編輯:關於Android編程
recyclerView是android5.0之後推出的一款新的View布局,功能相較於ListView有過之而無不及,相信在以後的學習和工作中都將可能會用上,這兩天自己在邊看邊學其中功能與各種效果,現來博客與諸君分享,也為日後自己復習設下渠道。
首先,我們了解一下為什麼要叫做RecyclerView?
它不關心Item是否顯示在正確位置,如何顯示;不關心Item間如何分割;不關注Item增加和刪除的動畫效果;僅僅關注如何回收和服用View(即英文Recycle的譯義)。
那可能有人要問了,這些都是View裡比較重要的且頻繁使用的屬性和效果,都不關心的話,如何做到控制和實現呢?其實,不必擔心,我們可以通過LayoutManager來實現Item的顯示,ItemDecoration來自定義Item之間的分割線,以及ItemAnimator來完成Item增加和刪除時所需要的各種動畫(下面的文章會詳細介紹)。所以它的功能還是很強大的,值得我們深入研究!
知道了RecyclerView的概念,我們來大體了解一下它具備的功能:
1.ListView
2.GridView
3.橫向ListView
4.橫向GridView
5.瀑布流
6.定制Item增加和刪除動畫
大致為以上功能,是不是挺強大的。
工欲善其事必先利其器,下面給出2個需要使用到的鏈接:
https://gist.github.com/alexfu/0f464fc3742f134ccd1e
github上recyclerviewItemDecoration原地址
https://github.com/gabrielemariotti/RecyclerViewItemAnimators
github/上recyclerview動畫效果集合原地址
下面進入今天的主題:由於我們的工程依賴android.support.v7包裡的recyclerViewjar包,建立工程時要找到你的sdk存放路徑的extras/android/support/v7/recyclerview/libs文件目錄下的jar包拷貝到工程目錄libs下,才能實現全部功能!
首先我們要首先ListView,寫兩個方法:initViews();initDatas();
private void initDatas() { mDatas = new ArrayList(); for (int i = 'A'; i <= 'z'; i++) { mDatas.add("" + (char) i); } } private void initViews() { mRecyclerView = (RecyclerView) findViewById(R.id.id_recyclerview); }
這兩個方法用來創建View和存放數據。這裡我放的是A-z。
然後創一個SimpleAdapter來適配主界面。這裡需要注意的是要繼承RecyclerView.Adapter
class MyViewHolder extends ViewHolder { TextView tv; public MyViewHolder(View arg0) { super(arg0); tv = (TextView) arg0.findViewById(R.id.id_tv); }這裡我就給每個Item一個TextView,然後通過我們自己的ViewHolder來初始化它。
另外還要重寫父類的方法:
@Override public int getItemCount() { return mDatas.size(); } @Override public void onBindViewHolder(final MyViewHolder holder, final int pos) { holder.tv.setText(mDatas.get(pos)); // click setUpItemEvent(holder); } @Override public MyViewHolder onCreateViewHolder(ViewGroup arg0, int arg1) { View view = mInflater.inflate(R.layout.item_simple_textview, arg0, false); MyViewHolder viewHolder = new MyViewHolder(view); return viewHolder; }這裡主要關注第二個和第三個方法,顧名思義就是綁定ViewHolder和創建Viewholder,
綁定裡用位置來設置Item內Text顯示的文字,setUpItemEvent(holder);這個方法後面會講到大家先忽略。然後Create方法裡就是初始化View工作,要創建一個item_simple_textview布局文件,裡面只放了一個TextView這裡我就不做過多贅述,最後返回我們的viewHolder。別忘了做綁定,
mAdapter = new SimpleAdapter(this, mDatas);
mRecyclerView.setAdapter(mAdapter);
還要給布局設置一個管理器:
// 設置recyclerview的布局管理 LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false); mRecyclerView.setLayoutManager(layoutManager);
然而此時我們運行程序會發現雖然ListView正常展示了,可是Item直接並沒有分割。
看起來很不舒服,接下來,我們就完成自定義分割線的工作。
由於RecyclerView自身並不能為Item添加分割線,所以我們采用外部開源文件的方法叫做PiderItemDecoration,該方法可以在正文開篇的地址裡找到並下載。
// 設置recyclerview的Item分割線,通過抽象類來控制 mRecyclerView.addItemDecoration(new PiderItemDecoration(this, PiderItemDecoration.VERTICAL_LIST));這裡給Item加一個垂直方向的默認的分割線。(稍後說下自定義)可以得到如下效果
但是,如果默認的分割線不合你的胃口,你完全可以自定義你想要的分割線樣式。這就需要我們對開源代碼進行簡單的分析!
public PiderItemDecoration(Context context, int orientation) { final TypedArray a = context.obtainStyledAttributes(ATTRS); mPider = a.getDrawable(0); a.recycle(); setOrientation(orientation); }這是PiderItemDecoration類的構造方法,從中我們不難看出a對象是從context.obtainStyledAttributes(ATTRS);中獲取到的,也就是說從theme中可以得到,這樣我們就可以自己定義一個shape放入theme裡,就可以給方法查找和調用了。
這裡我們寫了一個4dp高度的矩形,中間有三種顏色的漸變來作為我們的分割線。
然後由於我使用的SDK是6.0版本,所以講它放入values-v14包裡。
然後再次運行程序,就可以得到我們想要的效果。
到這裡我們的ListView差不多就實現了。接下來說明一下各自布局的切換使用。
-------------------------------------------------------------------------------------------------------------------
我們用menu裡的item來實現不同布局的切換!
進入main.xml添加三個Item
分別代表ListView、GridView、瀑布流布局。然後根據id來設置點擊到不同Item時顯示的布局樣式。
@Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); switch (id) { case R.id.action_add: mAdapter.addData(1); break; case R.id.action_delete: mAdapter.deleteData(1); break; case R.id.action_listView: mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); break; case R.id.action_gridView: mRecyclerView.setLayoutManager(new GridLayoutManager(this, 3)); break; case R.id.action_staggered: Intent intent = new Intent(this, StaggeredActivity.class); startActivity(intent); break; default: break; } return false; }
GridView就這樣了,比較簡單,下面我們主要研究一下瀑布流的代碼。
我們把MainActivity和SimpleAdapter都拷貝一份,改名為StaggeredActivity和StaggeredAdapter。
為了防止代碼復寫的麻煩,直接在SimpleAdapter裡提供一個回調方法,供StaggeredAdapter使用,實現點擊和長按事件。
// 設置一個接口回調,給Item綁定一個點擊事件 public interface OnItemClickListener { void onItemClick(View view, int position); void onItemLongClick(View view, int position); } private OnItemClickListener onItemClickListener; public void setOnItemClickListener(OnItemClickListener listener) { this.onItemClickListener = listener; }
protected void setUpItemEvent(final MyViewHolder holder) { if (onItemClickListener != null) { holder.itemView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { int layoutPosition = holder.getLayoutPosition(); onItemClickListener.onItemClick(holder.itemView, layoutPosition); } }); } // longclick holder.itemView.setOnLongClickListener(new OnLongClickListener() { @Override public boolean onLongClick(View v) { int layoutPosition = holder.getLayoutPosition(); onItemClickListener.onItemLongClick(holder.itemView, layoutPosition); return false; } }); }這樣處理的話,就可以讓StaggeredAdapter的代碼更加簡潔:
public class StaggeredAdapter extends SimpleAdapter { private LayoutInflater mInflater; private Context mContext; private ListmDatas; private List mHeight; public StaggeredAdapter(Context context, List datas) { super(context, datas); mHeight = new ArrayList (); for (int i = 0; i < mDatas.size(); i++) { mHeight.add((int) (100 + Math.random() * 300)); } } @Override public void onBindViewHolder(MyViewHolder holder, int pos) { LayoutParams lp = (LayoutParams) holder.itemView.getLayoutParams(); lp.height = mHeight.get(pos); holder.itemView.setLayoutParams(lp); holder.tv.setText(mDatas.get(pos)); setUpItemEvent(holder); } }
關於Item增加和刪除的動畫:
在menu裡加入兩個圖標,增加和刪除,對應前面代碼所示的switch方法內add和delete方法。代碼如下:
public void addData(int pos) { mDatas.add(pos, "Insert one"); notifyItemInserted(pos); } public void deleteData(int pos) { mDatas.remove(pos); notifyItemRemoved(pos); }注意:這裡使用了notifyItemInserted和notifyItemRemoved兩個方法,它會導致點擊加入或者刪除Item後,新增的Item和刪除的Item後面那個Item的postion不變,因為他只notify了增加和移除,並沒有重繪View,所以後面代碼裡用getParamPosition()方法來得到View所顯示的Item的動態位置,就不會造成多個position相同的情況。
mRecyclerView.setItemAnimator(new DefaultItemAnimator());這裡我使用的默認的動畫效果,大家可以去開篇給出的鏈接下載動畫效果源碼,實現各種炫酷的動畫!
好了,基本的功能已經介紹的差不多了,更多的炫酷動畫和花式布局,需要靠我們更多的去研究和學習!本人也只是小白階段,跟著視頻學習完寫個博客記錄一下學習成果,方便以後的復習同時也能給需要的人帶來一點參考和建議吧。共勉!
學習從模仿開始一個星期完成的音樂播放器基本功能,具有下一首,上一首,暫停和隨機、順序和單曲等播放,以及保存上一次播放的狀態,缺少了歌詞顯示功能。使用了andbase框架的
Socket簡介在說Socket之前,我們有必要先來簡單介紹一下TCP/IP協議族,TCP/IP(Transmission Control Protocol/Intern
案例效果:實例分析: 在開發銀行相關客戶端的時候或者開發在線支付相關客戶端的時候經常要求用戶綁定銀行卡,其中銀行卡號一般需要空格分隔顯示,最常見的就是每4位數以空格進行分
仿滴滴出行十大司機評選活動說明前言:最近在使用滴滴出行的時候發現了一個有意思的View界面,看到心動的View就會想著動手去畫一遍,本篇只是大概的模仿一下自定義的View