編輯:關於Android編程
RecyclerView的方法:
Adapter中的方法:
見圖:
package com.cqc.recyclerview01; import android.content.Context; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { private RecyclerView recyclerView; private Context context; private Listlist = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); context = this; initData(); recyclerView = (RecyclerView) findViewById(R.id.recyclerView); recyclerView.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)); recyclerView.setAdapter(new MyAdapter()); } private void initData() { list.clear(); for (int i = 0; i < 100; i++) { list.add("item" + i); } } public class MyAdapter extends RecyclerView.Adapter { private MyHolder myHolder; @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { TextView tv = new TextView(context); tv.setHeight(50); myHolder = new MyHolder(tv); return myHolder; } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { // MyHolder myHolder = (MyHolder) holder; myHolder = (MyHolder) holder; myHolder.textView.setText(list.get(position)); } @Override public int getItemCount() { return 100; } } public class MyHolder extends RecyclerView.ViewHolder { public TextView textView; public MyHolder(View itemView) { super(itemView); textView = (TextView) itemView; } } }
我們發現recyclerview沒有分割線,需要調用mRecyclerView.addItemDecoration()添加分割線, 但是ItemDecoration是抽象類,需要我們自己實現。
package com.cqc.recyclerview01; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.View; /** * RecyclerView添加分割線(當使用LayoutManager為LinearLayoutManager時) * 該類源於:http://blog.csdn.net/lmj623565791/article/details/45059587 */ public class DividerItemDecoration extends RecyclerView.ItemDecoration { private static final int[] ATTRS = new int[]{ android.R.attr.listDivider }; public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL; public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL; private Drawable mDivider; private int mOrientation; public DividerItemDecoration(Context context, int orientation) { final TypedArray a = context.obtainStyledAttributes(ATTRS); mDivider = a.getDrawable(0); a.recycle(); setOrientation(orientation); } public void setOrientation(int orientation) { if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) { throw new IllegalArgumentException("invalid orientation"); } mOrientation = orientation; } @Override public void onDraw(Canvas c, RecyclerView parent) { Log.v("recyclerview - itemdecoration", "onDraw()"); if (mOrientation == VERTICAL_LIST) { drawVertical(c, parent); } else { drawHorizontal(c, parent); } } public void drawVertical(Canvas c, RecyclerView parent) { final int left = parent.getPaddingLeft(); final int right = parent.getWidth() - parent.getPaddingRight(); final int childCount = parent.getChildCount(); for (int i = 0; i < childCount; i++) { final View child = parent.getChildAt(i); android.support.v7.widget.RecyclerView v = new android.support.v7.widget.RecyclerView(parent.getContext()); final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child .getLayoutParams(); final int top = child.getBottom() + params.bottomMargin; final int bottom = top + mDivider.getIntrinsicHeight(); mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } } public void drawHorizontal(Canvas c, RecyclerView parent) { final int top = parent.getPaddingTop(); final int bottom = parent.getHeight() - parent.getPaddingBottom(); final int childCount = parent.getChildCount(); for (int i = 0; i < childCount; i++) { final View child = parent.getChildAt(i); final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child .getLayoutParams(); final int left = child.getRight() + params.rightMargin; final int right = left + mDivider.getIntrinsicHeight(); mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } } @Override public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) { if (mOrientation == VERTICAL_LIST) { outRect.set(0, 0, 0, mDivider.getIntrinsicHeight()); } else { outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0); } } }
然後在mainActivity中調用:
recyclerView.addItemDecoration(new DividerItemDecoration(context,LinearLayoutManager.VERTICAL));//添加分割線
item_divider.xml
如何使用自定義的分割線:styles.xml
效果圖:
先在adapter中設置回調
//設置點擊回調 public interface OnItemClickListener { void onItemClickListerner(View view, int position); void onItemLongClickListener(View view, int position); } private OnItemClickListener mOnItemClickListener; public void setOnItemClickListener(OnItemClickListener mOnItemClickListener) { this.mOnItemClickListener = mOnItemClickListener; }
然後在onBindViewHolder(…)中調用點擊事件監聽
//如果設置了回調,則調用點擊事件 if (mOnItemClickListener != null) { holder.textView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mOnItemClickListener.onItemClickListerner(v, position); } }); holder.textView.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { mOnItemClickListener.onItemLongClickListener(v, position); return true;//事件被處理 } }); }
最後在activity中使用點擊事件
//點擊事件(用adapter調用點擊方法) adapter.setOnItemClickListener(new MyAdapter.OnItemClickListener() { @Override public void onItemClickListerner(View view, int position) { Toast.makeText(context,"短點擊",Toast.LENGTH_SHORT).show(); } @Override public void onItemLongClickListener(View view, int position) { Toast.makeText(context,"長點擊",Toast.LENGTH_SHORT).show(); } });
效果圖:
方法: 添加item:adapter.notifyItemInserted(position) 刪除item:adapter.notifyItemRemoved(position);
btn_add.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { list.add(0,"btn_add"); // adapter.notifyDataSetChanged();//也可以,但是沒有動畫效果 adapter.notifyItemInserted(0); recyclerView.scrollToPosition(0);//滑動到第一個item,不加不會滑動到頂部。 } }); btn_delete.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { list.remove(0); adapter.notifyDataSetChanged();//也可以,但是沒有動畫效果 // adapter.notifyItemRemoved(0); } });
recyclerView.setItemAnimator(new DefaultItemAnimator());//item添加移出動畫
1 onCreateViewHolder(…)不可以復用holder,必須new。
if (myHolder == null){ myHolder = new MyHolder(tv); }
2 onCreateViewHolder(…)中的holder和onBindViewHolder(RecyclerView.ViewHolder holder, int position) {。。}中的holder就是我們創建的MyHolder,可以直接進行格式轉換,也可以聲明成員變量。
public class MyAdapter extends RecyclerView.Adapter { private MyHolder myHolder; @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { TextView tv = new TextView(context); tv.setHeight(50); myHolder = new MyHolder(tv); return myHolder; } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { // MyHolder myHolder = (MyHolder) holder; myHolder = (MyHolder) holder; myHolder.textView.setText(list.get(position)); } @Override public int getItemCount() { return 100; } }
3 最好先創建類ViewHolder,再創建Adapter,這樣可以使用直接指定泛型,就不需要再格式轉換了。
public class MyAdapter extends RecyclerView.Adapter
4 item的高度設為match_parent,父布局設置100dp,item的高無效
父布局設置具體的高度,子view設match_parent,這是無效的。 方法一:必須給子view(textview設置具體的數值),父布局math——parent 方法二:item的view:使用 LayoutInflater.from(mContext).inflate(R.layout.item_layout, parent, false); 而不是其他任何方法!(View.inflate(..))
5 item的子view(textview)寬度match_parent,父布局的寬度也是match_parent,但是仍然無法充滿屏幕。
方法:item的view:使用LayoutInflater.from(mContext).inflate(R.layout.item_layout, parent, false); 而不是其他任何方法!(View.inflate(..))
6 總結:結合4+5,使用View.inflate(context, R.layout.item_main, null);創建item的view,會導致item的view高度無效,子view(textview)的高寬無效。
方法:item的view:使用LayoutInflater.from(mContext).inflate(R.layout.item_layout, parent, false); 而不是其他任何方法! 錯誤:(View.inflate(context, R.layout.item_main, null) 錯誤:LayoutInflater.from(context).inflate(R.layout.item_main,null))
本篇文章的主要內容是說圖片的內存緩存和從網絡異步獲取圖片的過程工程效果圖如下: 代碼中部分不常見的屬性解釋如下(百度也可以找到的)android:numCo
題外話這篇本來和之前的系列要一起出的,但是因為中間公司要發布一個版本,給耽擱了,今天工作做完了,又閒了下來。所以就又來繼續jenkins構建Android項目持續集成系列
一、概述最新github上開源了很多熱補丁動態修復框架,大致有:上述三個框架呢,根據其描述,原理都來自:安卓App熱補丁動態修復技術介紹,以及Android
最近需要實現一個城市列表的快速索引功能。類似於聯系人應用,根據姓名首字母快速索引功能。 要實現這個功能只需要解決兩個問題: 1、對列表進行分組(具有同一特征