1.自定義view基礎
2.RecyclerView的使用
3.自定義RecyclerView.ItemDecorationandroid
1.最終效果以下:segmentfault
2.實現思路api
3.詳細設計app
4.具體實現ide
dependencies { .......... api 'com.android.support:recyclerview-v7:28.0.0' }
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <android.support.v7.widget.RecyclerView android:id="@+id/my_recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" android:scrollbars="horizontal" /> </RelativeLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/item_title" android:text="New Text" android:textSize="15sp" android:layout_marginLeft="30dp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="New Text" android:layout_marginLeft="30dp" android:textSize="15sp" android:id="@+id/item_text" android:layout_below="@+id/item_title" /> </LinearLayout>
public class MyAdapter extends RecyclerView.Adapter { private LayoutInflater inflater; private ArrayList<HashMap<String,Object>> listitem; //構造函數,傳入數據 public MyAdapter(Context context,ArrayList<HashMap<String, Object>> listitem) { this.inflater = LayoutInflater.from(context); this.listitem = listitem; } class ViewHolder extends RecyclerView.ViewHolder{ private TextView title,text; public ViewHolder(@NonNull View itemView) { super(itemView); title = itemView.findViewById(R.id.item_title); text = itemView.findViewById(R.id.item_text); } public TextView getTitle() { return title; } public TextView getText() { return text; } } @NonNull @Override public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { return new ViewHolder(inflater.inflate(R.layout.list_cell,null)); //綁定item佈局 } @Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) { //綁定數據到ViewHolder ViewHolder vh = (ViewHolder) viewHolder; vh.title.setText((CharSequence) listitem.get(i).get("ItemTitle")); vh.text.setText((CharSequence) listitem.get(i).get("ItemText")); } @Override public int getItemCount() { return listitem.size(); } }
public class DividerItemDecoration extends RecyclerView.ItemDecoration { //軸點畫筆 private final Paint mPaint; //時分畫筆 private final Paint mPaint1; //年月畫筆 private final Paint mPaint2; //itemView 左 上 偏移量 private int itemView_leftinterval; private int itemView_topintervarl; //軸點半徑 private int circle_radius; private final Bitmap mIcon; //在構造函數裏初始化須要屬性 public DividerItemDecoration(Context context){ mPaint = new Paint(); mPaint.setColor(Color.RED);//設置畫筆顏色爲紅色 mPaint1 = new Paint(); mPaint1.setColor(Color.BLUE); mPaint1.setTextSize(30);//設置繪製字體大小 mPaint2 = new Paint(); mPaint2.setColor(Color.BLUE); mPaint2.setTextSize(15); itemView_leftinterval = 200; //左偏移長度200 itemView_topintervarl = 50; //上偏移長度50 circle_radius = 10;//軸點半徑爲10 mIcon = BitmapFactory.decodeResource(context.getResources(),R.mipmap.logo); } @Override public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { super.getItemOffsets(outRect, view, parent, state); //設置itemview的左上偏移量,即爲onDraw可繪製的區域 outRect.set(itemView_leftinterval,itemView_topintervarl,0,0); } @Override public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { super.onDraw(c, parent, state); //獲取RecyclerView的Child的個數 int childCount = parent.getChildCount(); //遍歷每一個item,分別獲取他們的位置信息,而後在繪製對應的分割線 for (int i=0;i<childCount;i++){ View view = parent.getChildAt(i);//獲取每一個item對象 /** * 繪製軸點 */ // 軸點 = 圓 = 圓心(x,y) float centerX = view.getLeft() - itemView_leftinterval/3; float centerY = view.getTop() - itemView_topintervarl+(itemView_topintervarl+view.getHeight()/2); // 繪製軸點圓 //c.drawCircle(centerX,centerY,circle_radius,mPaint); c.drawBitmap(mIcon,centerX-circle_radius,centerY-circle_radius,mPaint); /** * 繪製上半軸線 */ // 上端點座標(x,y) float upLine_up_x = centerX; float upLine_up_y =view.getTop()-itemView_topintervarl; // 下端點座標(x,y) float upLine_down_x = centerX; float upLine_down_y = centerY-circle_radius; c.drawLine(upLine_up_x,upLine_up_y,upLine_down_x,upLine_down_y,mPaint);//繪製下半軸線 /** * 繪製下半軸線 */ // 上端點座標(x,y) float bottomLine_up_x = centerX; float bottom_up_y = centerY + circle_radius; // 下端點座標(x,y) float bottomLine_bottom_x = centerX; float bottomLine_bottom_y = view.getBottom(); //繪製下半部軸線 c.drawLine(bottomLine_up_x, bottom_up_y, bottomLine_bottom_x, bottomLine_bottom_y, mPaint); /** * 繪製左邊時間文本 */ int index = parent.getChildAdapterPosition(view); //繪製時間文本起始位置 float Text_x = view.getLeft()-itemView_leftinterval*5/6; float Text_y = upLine_down_y; //根據item位置設置時間 switch (index){ case 0: //設置繪製日期 c.drawText("13:40",Text_x,Text_y,mPaint1); c.drawText("2018.4.03",Text_x+5,Text_y+20,mPaint2); break; case 1: //設置繪製日期 c.drawText("13:40",Text_x,Text_y,mPaint1); c.drawText("2018.4.03",Text_x+5,Text_y+20,mPaint2); break; case 2: //設置繪製日期 c.drawText("13:40",Text_x,Text_y,mPaint1); c.drawText("2018.4.03",Text_x+5,Text_y+20,mPaint2); break; case 3: //設置繪製日期 c.drawText("13:40",Text_x,Text_y,mPaint1); c.drawText("2018.4.03",Text_x+5,Text_y+20,mPaint2); break; case 4: //設置繪製日期 c.drawText("13:40",Text_x,Text_y,mPaint1); c.drawText("2018.4.03",Text_x+5,Text_y+20,mPaint2); break; case 5: //設置繪製日期 c.drawText("13:40",Text_x,Text_y,mPaint1); c.drawText("2018.4.03",Text_x+5,Text_y+20,mPaint2); break; default: c.drawText("已簽收",Text_x,Text_y,mPaint1); } } } }
public class MainActivity extends AppCompatActivity { private ArrayList<HashMap<String, Object>> itemlist; private RecyclerView rl; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initData(); initView(); } private void initData() { itemlist = new ArrayList<HashMap<String, Object>>(); HashMap<String, Object> map1 = new HashMap<String, Object>(); HashMap<String, Object> map2 = new HashMap<String, Object>(); HashMap<String, Object> map3 = new HashMap<String, Object>(); HashMap<String, Object> map4 = new HashMap<String, Object>(); HashMap<String, Object> map5 = new HashMap<String, Object>(); HashMap<String, Object> map6 = new HashMap<String, Object>(); map1.put("ItemTitle", "中國廣州公司已發出"); map1.put("ItemText", "發件人:妙卡迪文化公司"); itemlist.add(map1); map2.put("ItemTitle", "國際順豐已收入"); map2.put("ItemText", "等待中轉"); itemlist.add(map2); map3.put("ItemTitle", "國際順豐轉件中"); map3.put("ItemText", "下一站中國"); itemlist.add(map3); map4.put("ItemTitle", "中國順豐已收入"); map4.put("ItemText", "下一站江蘇理工大學"); itemlist.add(map4); map5.put("ItemTitle", "中國順豐派件中"); map5.put("ItemText", "等待派件"); itemlist.add(map5); map6.put("ItemTitle", "江蘇理工大學已簽收"); map6.put("ItemText", "收件人:darryrzhong"); itemlist.add(map6); } private void initView() { rl = findViewById(R.id.my_recycler_view); LinearLayoutManager manager = new LinearLayoutManager(this); rl.setLayoutManager(manager); //當知道Adapter內Item的改變不會影響RecyclerView寬高的時候,能夠設置爲true讓RecyclerView避免從新計算大小。 rl.setHasFixedSize(true); rl.addItemDecoration(new DividerItemDecoration(this));//設置自定義分割線 MyAdapter adapter = new MyAdapter(this,itemlist); rl.setAdapter(adapter); } }
至此,自定義RecyclerView就實現完成了.函數
歡迎關注做者darryrzhong,更多幹貨等你來拿喲.字體
更多精彩文章請關注