亚洲精品一二区_国产黄色片网站_99久久久成人国产精品_蜜臀网_国产精品一区二区三区免费_成人av中文字幕_91精品国产欧美一区二区成人

當(dāng)前位置:首頁(yè) > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 講師博文 > RecyclerView 學(xué)習(xí)筆記(一)---實(shí)現(xiàn)ListView

RecyclerView 學(xué)習(xí)筆記(一)---實(shí)現(xiàn)ListView 時(shí)間:2018-09-26      來(lái)源:未知

RecyclerView和ListView一樣,都是做列表顯示View子項(xiàng)的控件,它比ListView更高效和自由。

解析RecycleView,Recycle View,意思就是該控件只管回收和顯示View子項(xiàng),而對(duì)于如何顯示,顯示什么,它是不關(guān)心的,這給開(kāi)發(fā)過(guò)程帶來(lái)了極大的便利,比如ListView只能作為單列的列表顯示,GridView將一個(gè)界面表格化,通常情況下GridView通過(guò)強(qiáng)制View子項(xiàng)的寬度來(lái)顯示,在橫豎屏切換時(shí)的效果很差。

而RecycleView可以實(shí)現(xiàn):

ListView的功能

GridView的功能

橫向ListView的功能

橫向ScrollView的功能

瀑布流的功能

添加和刪除View子項(xiàng)

這些功能,非常強(qiáng)大,可以看出,它幾乎可以替代所有的動(dòng)態(tài)布局控件。

這么強(qiáng)大的動(dòng)態(tài)布局控件,得益于它的高度解耦,同樣,眾所周知,高度解耦,就意味著復(fù)雜度提升,相較于ListView、GridView等控件,RecycleView才實(shí)現(xiàn)過(guò)程是相對(duì)較復(fù)雜的。

RecyclerView的適配器需要繼承自RecyclerView.Adapter,在該適配器將要面向ViewHolder,也就是說(shuō),它內(nèi)部已經(jīng)實(shí)現(xiàn)了緩存復(fù)用。

實(shí)現(xiàn)LIstView功能

注意,RecyclerView是谷歌在support-v7包中添加的新組件,在開(kāi)發(fā)的時(shí)候,請(qǐng)?zhí)砑觭upport.v7包以及recyclerview-v7包,在module的Project Structure中的Dependencies部分添加如下圖所示:

首先創(chuàng)建RecyclerViewDemo1,活動(dòng):RecyclerViewDemo.java,layout:activiy_main.xml。

簡(jiǎn)單通過(guò)RecyclerView實(shí)現(xiàn)ListView的功能,那么首先就要理解ListView的實(shí)現(xiàn)過(guò)程。ListView是通過(guò)列表的的形式依次顯示一行行的數(shù)據(jù),從編程的角度出發(fā),就是一個(gè)LinnerLayout布局,方向?yàn)榭v向,依次添加進(jìn)數(shù)據(jù),后通過(guò)Scrolling實(shí)現(xiàn)滾動(dòng)屏幕。

再來(lái)對(duì)比RecyclerView,屏幕滾動(dòng)部分,在RecyclerView中已經(jīng)被實(shí)現(xiàn)好了,不需要關(guān)心,需要關(guān)心的就是布局,以及方向。

Java Code

recyclerView = (RecyclerView) findViewById(R.id.recycler_view);

//設(shè)置RecyclerView的布局管理器,為了模仿ListView,

//這里設(shè)置為Vertical的LinnerLayout

LinearLayoutManager manager = new LinearLayoutManager(this);

manager.setOrientation(OrientationHelper.VERTICAL);

recyclerView.setLayoutManager(manager);

上述代碼第5行,定義了一個(gè)LinearLayoutManager,傳入上下文為活動(dòng)的this,第6行將布局管理器的方向設(shè)置為VERTICAL,第7行,將這個(gè)布局管理器傳遞給RecyclerView。

對(duì)比ListView,這個(gè)時(shí)候我們只是擁有了一個(gè)ListView實(shí)例,數(shù)據(jù)源,適配器,以及View子項(xiàng)都還沒(méi)有說(shuō)明。

接下來(lái),創(chuàng)建一個(gè)View子項(xiàng),這個(gè)View子項(xiàng)可以顯示一張圖片,以及一段文字,可以使用一個(gè)TextView,當(dāng)然為了自由度,將聲明兩個(gè)控件,一個(gè)TextView、一個(gè)ImageView,分別用來(lái)顯示文字和圖片。

子View還是通過(guò)xml文件來(lái)定義。

XML Code

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="//schemas.android.com/apk/res/android"

android:orientation="horizontal" android:layout_width="match_parent"

android:layout_height="wrap_content"

android:background="@drawable/bg">

<ImageView

android:id="@+id/img_item"

android:layout_width="50dp"

android:layout_height="50dp" />

<TextView

android:id="@+id/txv_item"

android:gravity="center_vertical|center_horizontal"

android:textSize="21sp"

android:layout_width="match_parent"

android:layout_height="wrap_content" />

</LinearLayout>

上述代碼第7行和第11行,分別定義了一個(gè)ImageView和一個(gè)TextView,第4行,將打下限定在了wrap_content,View子項(xiàng)的大小可控。

四大組成部分中,已經(jīng)實(shí)現(xiàn)了兩部分,接下來(lái)是數(shù)據(jù)源,因?yàn)槭且粋(gè)Demo,這里數(shù)據(jù)源我們使用一個(gè)包含一個(gè)String和一個(gè)圖片Id的HashMap來(lái)實(shí)現(xiàn)。

Java Code

public HashMap getImgHash()

{

HashMapimgHash = new HashMap<>();

imgHash.put("0000", R.drawable.zero);

imgHash.put("1111", R.drawable.one);

imgHash.put("2222", R.drawable.two);

imgHash.put("3333", R.drawable.three);

imgHash.put("4444", R.drawable.four);

imgHash.put("5555", R.drawable.five);

imgHash.put("6666", R.drawable.six);

imgHash.put("7777", R.drawable.seven);

imgHash.put("8888", R.drawable.eight);

imgHash.put("9999", R.drawable.nine);

imgHash.put("aaaa", R.drawable.a);

imgHash.put("bbbb", R.drawable.b);

imgHash.put("cccc", R.drawable.c);

imgHash.put("dddd", R.drawable.d);

imgHash.put("eeee", R.drawable.e);

imgHash.put("ffff", R.drawable.f);

return imgHash;

}

RecyclerView實(shí)例有了,數(shù)據(jù)源有了,View子項(xiàng)有了,只剩下適配器將這些東西串聯(lián)起來(lái)了。

RecyclerView的Adapter,通常使用的是自定義的,這是由RecyclerView高度解耦,高度自由決定的,高度解耦意味著編碼復(fù)雜度上升。

在創(chuàng)建Adapter的時(shí)候,繼承自RecyclerView.Adapter,不過(guò)在這之前,請(qǐng)先建立一個(gè)自定義的ViewHolder類,這是因?yàn)椋赗ecyclerView的編碼過(guò)程中,緩存部分的工作已經(jīng)交由RecyclerView做好了,那么緩存什么,View子項(xiàng)是什么,需要程序員告知它。

Java Code

//自定義的ViewHolder

class MyViewHolder extends RecyclerView.ViewHolder{

public ImageView img;

public TextView textView;

public MyViewHolder(View itemView) {

super(itemView);

img = (ImageView) itemView.findViewById(R.id.img_item);

textView = (TextView) itemView.findViewById(R.id.txv_item);

}

}

編寫自定義適配器。

Java Code

public class MyAdapter extends RecyclerView.Adapter{

private Context context;

private List nameList;

private List imgList;

private LayoutInflater inflater;

private OnItemClickListener onItemClickListener;

//自定義構(gòu)造器,傳入上下文和數(shù)據(jù)源

public MyAdapter(Context context, HashMap imgHash) {

this.context = context;

imgList = new ArrayList<>();

nameList = new ArrayList<>();

for (Object o : imgHash.entrySet()){

Map.Entry entry = (Map.Entry) o;

String name = (String) entry.getKey();

int img = (int) entry.getValue();

nameList.add(name);

imgList.add(nameList.indexOf(name), img);

}

inflater = LayoutInflater.from(context);

}

//面向ViewHolder編程

@Override

public MyViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {

//View子項(xiàng)

View view = inflater.inflate(R.layout.item_recycler, viewGroup, false);

return new MyViewHolder(view);

  }

//面向ViewHolder編程

@Override

public void onBindViewHolder(MyViewHolder myViewHolder,

@SuppressLint("RecyclerView") final int i) {

//對(duì)View子項(xiàng)賦值

myViewHolder.img.setImageResource(imgList.get(i));

myViewHolder.textView.setText(nameList.get(i));

}

@Override

public int getItemCount() {

return nameList.size();

}

//自定義的ViewHolder

class MyViewHolder extends RecyclerView.ViewHolder{

public ImageView img;

public TextView textView;

//和View子項(xiàng)真正建立連接

public MyViewHolder(View itemView) {

super(itemView);

img = (ImageView) itemView.findViewById(R.id.img_item);

textView = (TextView) itemView.findViewById(R.id.txv_item);

}

}

}

四大組成部分已經(jīng)編寫完成,接下來(lái),

myAdapter = new MyAdapter(this, imgHash);

recyclerView.setAdapter(myAdapter);

完成適配器配置。

來(lái)看一下現(xiàn)象如下圖所示:

和ListView的效果很像,已經(jīng)將數(shù)據(jù)完整的顯示在活動(dòng)中,但是仔細(xì)看,會(huì)發(fā)現(xiàn),View子項(xiàng)和View子項(xiàng)之間沒(méi)有明顯的分隔。并沒(méi)有ListView中的分隔的效果。

對(duì)于RecyclerView來(lái)說(shuō),添加分隔線也是耦合事件,所以,當(dāng)想要分隔線的時(shí)候,需要自己添加。需要添加recyclerView.addItemDecoration()方法添加分隔線。該方法的參數(shù)需要一個(gè)RecycleView.ItemDecoration實(shí)例,該類是一個(gè)abstract的虛類,要實(shí)現(xiàn)該類需要做自定義操作,谷歌并沒(méi)有提供默認(rèn)的實(shí)現(xiàn)。

創(chuàng)建MyItemDecoration繼承自RecyclerView.ItemDecoration,觀察該類,需要重寫其onDraw方法,getItemOffsets方法。

Java Code

package com.hqyj.dev.recyclerviewdemo1;

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.view.View;

/**

* Created by jiyangkang on 2016/7/15 0015.

*/

public class MyItemDecoration extends RecyclerView.ItemDecoration {

private static final int[] ATTRS = new int[]{

android.R.attr.listDivider

};

private static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;

private static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;

private Drawable mDivider;

private int mOrientation;

//構(gòu)造器,從參數(shù)離別中拿出要繪制的Drawable

public MyItemDecoration(Context context, int orientation) {

//參數(shù)列表

final TypedArray a = context.obtainStyledAttributes(ATTRS);

//參數(shù)列表0項(xiàng)

mDivider = a.getDrawable(0);

//使用完參數(shù)列表之后一定要做recycle()

a.recycle();

try {

setmOrientation(orientation);

} catch (IllegalAccessException e) {

e.printStackTrace();

}

}

//選擇繪制什么樣的分隔線

@Override

public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {

super.onDraw(c, parent, state);

if (mOrientation == VERTICAL_LIST) {

drawVertiacl(c, parent, state);

} else {

drawHorizontal(c, parent, state);

}

}

public void setmOrientation(int orientation) throws IllegalAccessException {

if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {

throw new IllegalAccessException("invalid orientation");

}

mOrientation = orientation;

}

//縱向排列的View子項(xiàng)

public void drawVertiacl(Canvas c, RecyclerView parent, RecyclerView.State state) {

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);

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);

}

}

//橫向排列的View子項(xiàng)

public void drawHorizontal(Canvas c, RecyclerView parent, RecyclerView.State state) {

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, View view, RecyclerView parent, RecyclerView.State state) {

super.getItemOffsets(outRect, view, parent, state);

if (mOrientation == VERTICAL_LIST) {

outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());

} else {

outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);

}

}

}

自定義ItemDecoration寫好厚,就可以將其添加到RecyclerView中了。

添加recyclerView.addItemDecoration(new MyItemDecoration(this, LinearLayoutManager.VERTICAL));帶活動(dòng)的onCreate方法中。

再看展示的效果圖,如下圖:

可以看到,已經(jīng)有分隔線了,這個(gè)分隔線是我們?cè)贏TTRS中放入的第0個(gè)Drawable的id,我們知道它是來(lái)自android.R的,即系統(tǒng)集成的,使用該分隔線的一個(gè)好處就是,我們可以對(duì)其進(jìn)行自定義。

在res下的drawable目錄下創(chuàng)建一個(gè)shap,來(lái)設(shè)置一個(gè)漸變drawable.

XML Code

<?xml version="1.0" encoding="utf-8"?>

<shape xmlns:android="//schemas.android.com/apk/res/android"

android:shape="rectangle" >

<gradient

android:centerColor="#ff00ff00"

android:startColor="#ff0000ff"

android:endColor="#ffff0000"/>

<size android:height="2dp"/>

</shape>

然后在styles.xml中為工程的AppTheme中添加一個(gè)android:listDivider子項(xiàng),為listDivider賦值為定義好的drawable。

效果圖如下:

這樣的效果已經(jīng)和ListView很像了,但是,在點(diǎn)擊對(duì)應(yīng)的View子項(xiàng)的時(shí)候,會(huì)發(fā)現(xiàn),是沒(méi)有效果的,這是因?yàn)镽ecyclerView中,并沒(méi)有和ListView一樣的OnItemClickLisener接口。

還是因?yàn)镽ecyclerView高度解耦的緣故,而自定義監(jiān)聽(tīng)將更加自由。在Adapter中添加一個(gè)接口,用以監(jiān)聽(tīng)按鈕事件。

Java Code

public interface OnItemClickListener

{

void onClick(int position, String name, int imgSource);

void onLongClick(int position, String name, int imgSource);

}

public void setOnItemClickListener(OnItemClickListener onItemClickListener)

{

this.onItemClickListener = onItemClickListener;

}

@Override

public void onBindViewHolder(MyViewHolder myViewHolder, @SuppressLint("RecyclerView") final int i)

{

myViewHolder.img.setImageResource(imgList.get(i));

myViewHolder.textView.setText(nameList.get(i));

if (onItemClickListener != null)

{

myViewHolder.itemView.setOnClickListener(new View.OnClickListener()

{

@Override

public void onClick(View view)

{

onItemClickListener.onClick(i, nameList.get(i), imgList.get(i));

}

});

myViewHolder.itemView.setOnLongClickListener(new View.OnLongClickListener()

{

@Override

public boolean onLongClick(View view)

{

//onItemClickListener.onLongClick(i, nameList.get(i), imgList.get(i));

//removeData(i);

return false;

}

});

}

}

在調(diào)用Adapter的部分添加

Java Code

myAdapter.setOnItemClickListener(new MyAdapter.OnItemClickListener()

{

@SuppressLint("DefaultLocale")

@Override

public void onClick(int position, String name, int imgSource)

{

textView.setText(String.format("%d is clicked, %s is contained", position, name));

}

@SuppressLint("DefaultLocale")

@Override

public void onLongClick(int position, String name, int imgSource)

{

textView.setText(String.format("%d is Long clicked, %s is contained", position, name));

}

});

到此,點(diǎn)擊事件也已經(jīng)注冊(cè)到活動(dòng)中,點(diǎn)擊每個(gè)View子項(xiàng)都已經(jīng)有相應(yīng)。

但是,還有一個(gè)問(wèn)題,點(diǎn)擊事件發(fā)生的時(shí)候,View子項(xiàng)沒(méi)有任何反應(yīng),位View子項(xiàng)添加一個(gè)background,在Drawable里邊頂一個(gè)selector。就可以實(shí)現(xiàn)點(diǎn)擊事件發(fā)生時(shí)改變背景顏色的功能。

XML Code

<?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="//schemas.android.com/apk/res/android" >

<item android:state_pressed="true"

android:drawable="@color/colorBg_press"/>

<item android:drawable="@color/colorBg_default"/>

</selector>

至此,一個(gè)仿照的ListView就被實(shí)現(xiàn)出來(lái)了,而且更具靈活性,也更生動(dòng)。

在靈活性上,一個(gè)很重要的體現(xiàn)就是,可以任意的增加和刪除View子項(xiàng)。在上述的代碼中其實(shí)已經(jīng)可以看見(jiàn)一部分了,在長(zhǎng)按的監(jiān)聽(tīng)事件中,長(zhǎng)按發(fā)生時(shí),會(huì)將對(duì)應(yīng)的View子項(xiàng)從列表中刪除。

Java Code

public void removeData(int position){

nameList.remove(position);

imgList.remove(position);

notifyItemRemoved(position);

notifyDataSetChanged();//必須添加

}

notifyItemRemoved方法即為刪除方法。同樣的,還有一個(gè)為notifyItemInser(int position)的方法,用以插入一個(gè)View子項(xiàng)。View子項(xiàng)也是可以移動(dòng)的,方法為notifyItemMove(int fromPosition, int toPosition)。

上一篇:談?wù)剆ocket 套接字

下一篇:異步通信和同步通信簡(jiǎn)單對(duì)比

熱點(diǎn)文章推薦
華清學(xué)員就業(yè)榜單
高薪學(xué)員經(jīng)驗(yàn)分享
熱點(diǎn)新聞推薦
前臺(tái)專線:010-82525158 企業(yè)培訓(xùn)洽談專線:010-82525379 院校合作洽談專線:010-82525379 Copyright © 2004-2022 北京華清遠(yuǎn)見(jiàn)科技集團(tuán)有限公司 版權(quán)所有 ,京ICP備16055225號(hào)-5京公海網(wǎng)安備11010802025203號(hào)

回到頂部

主站蜘蛛池模板: 亚洲天堂久久精品成人 | 欧美特黄高清免费观看的 | 亚洲精品无码专区在线播放 | 久久国产精品偷 | 国产一区二区在线视频观看 | 中文字幕99在线精品视频免费看 | 久久伊人久久 | 妇少香港三日本三级视频 | 亚洲精品人人 | 男女做性免费视频 | 91.久久| 欧美乱理 | 九九九精品午夜在线观看 | 99在线热视频只有精品免费 | 免费a级毛片网站 | 在线中文字幕亚洲 | 韩国十九禁在在线观看 | 免费午夜网站 | 欧美视频一区二区三区 | 毛茸茸xxxx的视频 | 激情文学亚洲色图 | 日本一二三区高清 | 夜夜夜夜夜操 | 国产成人91青青草原精品 | 日本高清视频色 | 日日射日日干 | 欧美视频在线播放bbxxx | 日韩精品观看 | 日韩欧美在线视频一区二区 | 日日摸夜夜添免费毛片小说 | 99re热| 欧美xxxx做受欧美69 | 极品成人 | 国产一区二区福利 | 春色精品视频在线播放 | 夜夜草视频 | 伊人精品在线 | 日本高清视频免费在线观看 | 久久精品人人做人人爽97 | 日本欧美一区二区三区 | 一个人看aaaa免费中文 |