亚洲免费人人妻人人,cao78在线视频,福建一级毛片,91精品视频免费观看,高清另类图片操逼,日本特黄特色大片免费看,超碰欧美人人澡曰曰澡夜夜泛

RecyclerView使用 及 滑動(dòng)時(shí)加載圖片優(yōu)化方案 -電腦資料

電腦資料 時(shí)間:2019-01-01 我要投稿
【www.msguai.com - 電腦資料】

    RecyclerView使用 及 滑動(dòng)時(shí)加載圖片優(yōu)化方案

簡述

    本篇博文主要給大家分享關(guān)于RecyclerView控件的使用及通過繼承RecyclerView來實(shí)現(xiàn)滑動(dòng)時(shí)加載圖片的優(yōu)化方案,也同樣能解決防止圖片亂序的問題,之前有在網(wǎng)上有看到大神對(duì)Android中ListView異步加載圖片亂序問題進(jìn)行過分析,并深入剖析原理后分別給出了3種對(duì)應(yīng)的解決方案:一 、使用findViewWithTag,

RecyclerView使用 及 滑動(dòng)時(shí)加載圖片優(yōu)化方案

。二、使用弱引用關(guān)聯(lián)。三、使用Volley框架提供的NetworkImageView。

    看了之后思索了很久,后來才想到,哦,原來自己也一直這么在用。也算是一種解決方案吧,雖然不是從問題的根本進(jìn)行處理,但根據(jù)實(shí)際業(yè)務(wù)需要,也同樣能合理的解決。如以下兩種方案:

1、控制線程數(shù)量 + 數(shù)據(jù)分頁加載2、重寫onScrollStateChanged方法

    這個(gè)我們后面再談,下面先來看看RecyclerView控件的使用及我們?yōu)槭裁催x擇使用它。

RecyclerView的使用

    RecyclerView 位于package android.support.v7.widget; 包下,直接繼承了android.view.ViewGroup,是Android中新添加的一個(gè)用來取代ListView的滑動(dòng)控件,其靈活性與可替代性比ListView更優(yōu)秀,運(yùn)行原理與ListView類似,都是通過維護(hù)少量的View可展示大量的數(shù)據(jù)集。

    總結(jié)其優(yōu)點(diǎn):

一、標(biāo)準(zhǔn)化了ViewHolder,使用Adapter適配器時(shí),面向ViewHolder而不是單純的View,直接把ViewHolder的實(shí)現(xiàn)封裝起來,用戶只要實(shí)現(xiàn)自己的ViewHolder就可以了,該組件會(huì)自動(dòng)幫你回收并復(fù)用每一個(gè)item。不但變得更精簡,也變得更加容易使用,而且更容易組合設(shè)計(jì)出自己需要的滑動(dòng)布局。二、將Layout抽象成了一個(gè)LayoutManager,RecyclerView不負(fù)責(zé)子View的布局,而是通過使用LayoutManager來實(shí)現(xiàn)不同的布局效果,如使用LinearLayoutManager來指定方向,其默認(rèn)是垂直,也可以設(shè)置為水平,當(dāng)然你也可以自己來定義。

    我們來看看官方給出的示例:

    1.MyActivity.java

public class MyActivity extends Activity {      private RecyclerView mRecyclerView;      private RecyclerView.Adapter mAdapter;      private RecyclerView.LayoutManager mLayoutManager;        @Override      protected void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.my_activity);          mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);            // improve performance if you know that changes in content do not change the size of the RecyclerView         //如果確定每個(gè)item的內(nèi)容不會(huì)改變RecyclerView的大小,設(shè)置這個(gè)選項(xiàng)可以提高性能        mRecyclerView.setHasFixedSize(true);            // use a linear layout manager         //創(chuàng)建默認(rèn)的線性LayoutManager        mLayoutManager = new LinearLayoutManager(this);          mRecyclerView.setLayoutManager(mLayoutManager);            // specify an adapter (see also next example)         //設(shè)置Adapter        mAdapter = new MyAdapter(myDataset);          mRecyclerView.setAdapter(mAdapter);      }      ...  }

    LayoutManager:用來確定每一個(gè)item如何進(jìn)行排列擺放,何時(shí)展示和隱藏。提供默認(rèn)的動(dòng)畫效果,你也可以定義你自己的LayoutManager和添加刪除動(dòng)畫。在回收或重用一個(gè)View時(shí),LayoutManager會(huì)向適配器請(qǐng)求新的數(shù)據(jù)來替換舊的數(shù)據(jù),這種機(jī)制避免了創(chuàng)建過多的View和頻繁的調(diào)用findViewById方法。

2.MyAdapter

   

public class MyAdapter extends RecyclerView.Adapter<myadapter.viewholder>{      private String[] mDataset;        // Provide a reference to the type of views that you are using (custom viewholder)      //自定義的ViewHolder,持有每個(gè)Item的的所有界面元素    public static class ViewHolder extends RecyclerView.ViewHolder {          public TextView mTextView;          public ViewHolder(TextView v) {              super(v);              mTextView = v;          }      }        // Provide a suitable constructor (depends on the kind of dataset)      public MyAdapter(String[] myDataset) {          mDataset = myDataset;      }        // Create new views (invoked by the layout manager)     //創(chuàng)建新View,被LayoutManager調(diào)用    @Override      public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,                                                     int viewType) {          // create a new view          View v = LayoutInflater.from(parent.getContext())                                 .inflate(R.layout.my_text_view, parent, false);          // set the view's size, margins, paddings and layout parameters          ...          ViewHolder vh = new ViewHolder(v);          return vh;      }        // Replace the contents of a view (invoked by the layout manager)     //將數(shù)據(jù)與界面進(jìn)行綁定    @Override      public void onBindViewHolder(ViewHolder holder, int position) {          // - get element from your dataset at this position          // - replace the contents of the view with that element          holder.mTextView.setText(mDataset[position]);        }        // Return the size of your dataset (invoked by the layout manager)      //這個(gè)就不解釋了    @Override      public int getItemCount() {          return mDataset.length;      }  }</myadapter.viewholder>
Adapter:在使用RecyclerView之前,你需要一個(gè)繼承自RecyclerView.Adapter的適配器,作用是將數(shù)據(jù)與每一個(gè)item的界面進(jìn)行綁定。

    3.XML布局

    注:recyclerview No adapter attached; skipping layout 若出現(xiàn)該錯(cuò)誤,是由于跳過了布局,沒有Adapter與之對(duì)接的原因。

    附:

    ①設(shè)置為橫向的List:

mLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
②設(shè)置Grid布局列表,聲明LayoutManager為GridLayoutManager即可:

   

mLayoutManager = new GridLayoutManager(context,columNum);mRecyclerView.setLayoutManager(mLayoutManager);
③瀑布流布局

   

//使用StaggeredGridLayoutManager

    從上述例子可以看出,RecyclerView的用法并不復(fù)雜,反而更靈活好用,它將數(shù)據(jù)、排列方式、數(shù)據(jù)的展示方式都分割開來,自定義的形式也非常多,非常靈活。下方共享一個(gè)開源示例,且解決了ScrollView嵌套R(shí)ecyclerView無法顯示的問題:

   

   

    下載鏈接:http://download.csdn.net/detail/gao_chun/9124221

滑動(dòng)時(shí)圖片優(yōu)化方案描述

    1、控制線程數(shù)量 + 數(shù)據(jù)分頁加載

    我們?cè)谑褂没瑒?dòng)控件呈現(xiàn)圖片數(shù)據(jù)時(shí),顯然都會(huì)在getView方法里創(chuàng)建新的線程去異步加載圖片,不可能有一百條或上千條數(shù)據(jù)一口氣全部塞過來吧(當(dāng)然你要這么干也是可以的),那么根據(jù)項(xiàng)目需求必然會(huì)進(jìn)行分頁加載,咱一頁顯示的item條數(shù)也別太夸張就好。而且,當(dāng)我們點(diǎn)擊屏幕快速向下滑動(dòng)時(shí),每個(gè)Item都會(huì)調(diào)用getView一次,必然會(huì)創(chuàng)建出很多線程去加載圖片的URL資源,控制好線程的數(shù)量,加個(gè)線程池就非常有必要了。為了避免OOM導(dǎo)致FC,注意圖片需要緩存,因?yàn)閺膬?nèi)存中讀取圖片資源是非?斓摹

    2、重寫onScrollStateChanged方法

    這種方案用的也很普遍,相信只要細(xì)心觀察,就會(huì)發(fā)現(xiàn)類似微博、Facebook、或者一些圖片壁紙類的APP,在滑動(dòng)時(shí)未加載的圖片是不會(huì)立刻加載呈現(xiàn)的,只有當(dāng)滑動(dòng)停止后才會(huì)加載,這里需要注意一點(diǎn)的是,只加載當(dāng)前屏幕內(nèi)的圖片。這么一說可能有童鞋就明白了。我們可以通過繼承RecyclerView去自定義一個(gè)滑動(dòng)控件,通過繼承OnScrollListener后重寫其 onScrolled方法 和 onScrollStateChanged 等方法來做相應(yīng)處理。

    例如:

private class AutoLoadScrollListener extends OnScrollListener {          //......       public void onScrollStateChanged(RecyclerView recyclerView, int newState){       }    }
我們通過 extends OnScrollListener 并且 @Override 其 onScrollStateChanged 方法,通過判斷state來處理,此處對(duì)其滾動(dòng)的狀態(tài)newState做一個(gè)說明,方面大家了解學(xué)習(xí),分別有3個(gè)狀態(tài),即 0 - 1 - 2:

    狀態(tài)為0時(shí):當(dāng)前屏幕停止?jié)L動(dòng);

    狀態(tài)為1時(shí):屏幕在滾動(dòng) 且 用戶仍在觸碰或手指還在屏幕上;

    狀態(tài)為2時(shí):隨用戶的操作,屏幕上產(chǎn)生的慣性滑動(dòng);

實(shí)現(xiàn)

    我們就不自己去寫那些異步加載圖片,緩存啥的代碼塊了,簡單明了,直接使用ImageLoader就可以。下面通過實(shí)例講解該功能的實(shí)現(xiàn),老規(guī)矩,先來效果圖:

   

    先來瞄瞄activity_main.xml布局文件:

<li><relativelayout android:background="#00F1A0" android:id="@+id/layout_titlebar" android:layout_height="48dp" android:layout_width="match_parent"><textview android:gravity="center" android:id="@+id/text_title" android:layout_height="match_parent" android:layout_width="match_parent" android:text="好慌~" android:textcolor="@android:color/white" android:textsize="16dp"></textview></relativelayout><framelayout android:id="@+id/frame_container" android:layout_height="match_parent" android:layout_width="match_parent"></framelayout></linearlayout>

    很簡單,用了一個(gè)Fragment而已,再來看看主Fragment的布局:

<framelayout android:background="@android:color/white" android:layout_height="match_parent" android:layout_width="match_parent" xmlns:android="http://schemas.android.com/apk/res/android"><org.gaochun.view.autoloadrecyclerview android:id="@+id/recycler_view" android:layout_height="match_parent" android:layout_width="match_parent" android:scrollbars="vertical"></org.gaochun.view.autoloadrecyclerview></framelayout>

    我們使用了 SwipeRefreshLayout 中包裹了自定義的 AutoLoadRecyclerView,關(guān)于SwipeRefreshLayout 控件的使用,大家可以自行百度,這里就不多說了,

電腦資料

RecyclerView使用 及 滑動(dòng)時(shí)加載圖片優(yōu)化方案》(http://www.msguai.com)。有盆友可能會(huì)說,挖槽,好慌~ ,這測(cè)試圖哪來的,貌似還挺清晰的哇,好吧,只能幫你到這了:

package org.gaochun.myapplication;import java.util.ArrayList;import java.util.List;/** * Created by gao_chun on 2015/9/18. */public class ImageUrl {    public static List<string>imageList(){        List<string>mUrls = new ArrayList<string>();        mUrls.add(http://e.hiphotos.baidu.com/image/pic/item/a1ec08fa513d2697e542494057fbb2fb4316d81e.jpg);        mUrls.add(http://c.hiphotos.baidu.com/image/pic/item/30adcbef76094b36de8a2fe5a1cc7cd98d109d99.jpg);        mUrls.add(http://h.hiphotos.baidu.com/image/pic/item/7c1ed21b0ef41bd5f2c2a9e953da81cb39db3d1d.jpg);        mUrls.add(http://g.hiphotos.baidu.com/image/pic/item/55e736d12f2eb938d5277fd5d0628535e5dd6f4a.jpg);        mUrls.add(http://e.hiphotos.baidu.com/image/pic/item/4e4a20a4462309f7e41f5cfe760e0cf3d6cad6ee.jpg);        mUrls.add(http://b.hiphotos.baidu.com/image/pic/item/9d82d158ccbf6c81b94575cfb93eb13533fa40a2.jpg);        mUrls.add(http://e.hiphotos.baidu.com/image/pic/item/4bed2e738bd4b31c1badd5a685d6277f9e2ff81e.jpg);        mUrls.add(http://www.huabian.com/uploadfile/2014/1202/20141202025659854.jpg);        mUrls.add(http://www.huabian.com/uploadfile/2014/1202/20141202025700989.jpg);        mUrls.add(http://g.hiphotos.baidu.com/image/pic/item/0d338744ebf81a4c87a3add4d52a6059252da61e.jpg);        mUrls.add(http://a.hiphotos.baidu.com/image/pic/item/f2deb48f8c5494ee5080c8142ff5e0fe99257e19.jpg);        mUrls.add(http://f.hiphotos.baidu.com/image/pic/item/4034970a304e251f503521f5a586c9177e3e53f9.jpg);        mUrls.add(http://b.hiphotos.baidu.com/image/pic/item/279759ee3d6d55fbb3586c0168224f4a20a4dd7e.jpg);        mUrls.add(http://img2.xkhouse.com/bbs/hfhouse/data/attachment/forum/corebbs/2009-11/2009113011534566298.jpg);        mUrls.add(http://a.hiphotos.baidu.com/image/pic/item/e824b899a9014c087eb617650e7b02087af4f464.jpg);        mUrls.add(http://c.hiphotos.baidu.com/image/pic/item/9c16fdfaaf51f3de1e296fa390eef01f3b29795a.jpg);        mUrls.add(http://d.hiphotos.baidu.com/image/pic/item/b58f8c5494eef01f119945cbe2fe9925bc317d2a.jpg);        mUrls.add(http://h.hiphotos.baidu.com/image/pic/item/902397dda144ad340668b847d4a20cf430ad851e.jpg);        mUrls.add(http://b.hiphotos.baidu.com/image/pic/item/359b033b5bb5c9ea5c0e3c23d139b6003bf3b374.jpg);        mUrls.add(http://a.hiphotos.baidu.com/image/pic/item/8d5494eef01f3a292d2472199d25bc315d607c7c.jpg);        mUrls.add(http://b.hiphotos.baidu.com/image/pic/item/e824b899a9014c08878b2c4c0e7b02087af4f4a3.jpg);        mUrls.add(http://g.hiphotos.baidu.com/image/pic/item/6d81800a19d8bc3e770bd00d868ba61ea9d345f2.jpg);        return mUrls;    }}</string></string></string>

    下面來看看主要的類AutoLoadRecyclerView,其實(shí)這個(gè)類也很簡單:

public class AutoLoadRecyclerView extends RecyclerView implements LoadFinishCallBack {	private onLoadMoreListener loadMoreListener;	//加載更多回調(diào)	private boolean isLoadingMore;					//是否加載更多	public AutoLoadRecyclerView(Context context) {		this(context, null);	}	public AutoLoadRecyclerView(Context context, AttributeSet attrs) {		this(context, attrs, 0);	}	public AutoLoadRecyclerView(Context context, AttributeSet attrs, int defStyle) {		super(context, attrs, defStyle);		isLoadingMore = false;	//默認(rèn)無需加載更多		setOnScrollListener(new AutoLoadScrollListener(null, true, true));	}	/**	 * 配置顯示圖片,需要設(shè)置這幾個(gè)參數(shù),快速滑動(dòng)時(shí),暫停圖片加載	 *	 * @param imageLoader	ImageLoader實(shí)例對(duì)象	 * @param pauseOnScroll	 * @param pauseOnFling	 */	public void setOnPauseListenerParams(ImageLoader imageLoader, boolean pauseOnScroll, boolean pauseOnFling) {		setOnScrollListener(new AutoLoadScrollListener(imageLoader, pauseOnScroll, pauseOnFling));	}	public void setLoadMoreListener(onLoadMoreListener loadMoreListener) {		this.loadMoreListener = loadMoreListener;	}	@Override	public void loadFinish(Object obj) {		isLoadingMore = false;	}	//加載更多的回調(diào)接口	public interface onLoadMoreListener {		void loadMore();	}	/**	 * 滑動(dòng)自動(dòng)加載 	 */	private class AutoLoadScrollListener extends OnScrollListener {		private ImageLoader imageLoader;		private final boolean pauseOnScroll;		private final boolean pauseOnFling;		public AutoLoadScrollListener(ImageLoader imageLoader, boolean pauseOnScroll, boolean pauseOnFling) {			super();			this.pauseOnScroll = pauseOnScroll;			this.pauseOnFling = pauseOnFling;			this.imageLoader = imageLoader;		}		@Override		public void onScrolled(RecyclerView recyclerView, int dx, int dy) {			super.onScrolled(recyclerView, dx, dy);			//由于GridLayoutManager是LinearLayoutManager子類,所以也適用			if (getLayoutManager() instanceof LinearLayoutManager) {				int lastVisibleItem = ((LinearLayoutManager) getLayoutManager()).findLastVisibleItemPosition();				int totalItemCount = AutoLoadRecyclerView.this.getAdapter().getItemCount();				//有回調(diào)接口,且不是加載狀態(tài),且計(jì)算后剩下2個(gè)item,且處于向下滑動(dòng),則自動(dòng)加載				if (loadMoreListener != null && !isLoadingMore && lastVisibleItem >= totalItemCount -						2 && dy > 0) {					loadMoreListener.loadMore();					isLoadingMore = true;				}			}		}		//當(dāng)屏幕停止?jié)L動(dòng)時(shí)為0;當(dāng)屏幕滾動(dòng)且用戶使用的觸碰或手指還在屏幕上時(shí)為1;由于用戶的操作,屏幕產(chǎn)生慣性滑動(dòng)時(shí)為2		@Override		public void onScrollStateChanged(RecyclerView recyclerView, int newState) {			//根據(jù)newState狀態(tài)做處理			if (imageLoader != null) {				switch (newState) {					case 0:						imageLoader.resume();						break;					case 1:						if (pauseOnScroll) {							imageLoader.pause();						} else {							imageLoader.resume();						}						break;					case 2:						if (pauseOnFling) {							imageLoader.pause();						} else {							imageLoader.resume();						}						break;				}			}		}	}

    也就是說,我們通過定義了一個(gè) setOnPauseListenerParams 方法去設(shè)置滑動(dòng)監(jiān)聽事件setOnScrollListener,并通過定義內(nèi)部類AutoLoadScrollListener去@Override相關(guān)方法并做相應(yīng)的處理。

最新文章