国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

安卓之Gallery實(shí)現(xiàn)刷新加載和分頁(yè)加載

2019-11-09 18:09:10
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

   在項(xiàng)目的進(jìn)展中使用了Gallery控件展示相冊(cè),由于Gallery控件已經(jīng)被谷歌棄用,所以建議大家考慮使用新的控件來(lái)代替,及時(shí)跟上潮流。不過(guò)本篇的重點(diǎn)不是討論被棄用的Gallery控件,而是來(lái)討論怎么使用Gallery控件實(shí)現(xiàn)類似ListView控件的刷新和加載功能,因?yàn)轫?xiàng)目里面使用的是PullToRefresh的庫(kù),但是該庫(kù)好像并不支持Gallery的刷新和加載功能,所以只得自己參考別人的寫法來(lái)實(shí)現(xiàn)該功能了。本文提供一種實(shí)現(xiàn)思路,希望可以幫到大家。(源碼附在文后,歡迎大家下載,不要分!?。?/p>

  先看下效果圖(用的是在線GIF生成工具):

 

下面開始正文。首先講一下實(shí)現(xiàn)的思路:Gallery是橫向滑動(dòng)的控件,我們類似ListView實(shí)現(xiàn)刷新一樣,當(dāng)滑動(dòng)到第0項(xiàng)時(shí)候,開始刷新操作,滑動(dòng)到最后一項(xiàng)的時(shí)候進(jìn)行分頁(yè)加載的操作。

順著這個(gè)思路,我們開始編碼了:首先是一頭一尾兩個(gè)界面,刷新界面和加載更多的界面,兩個(gè)界面布局類似,就只貼一個(gè)布局文件了。

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical" android:layout_width="match_parent"    android:layout_height="match_parent">    <PRogressBar        style="?android:attr/progressBarStyleLarge"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentTop="true"        android:layout_centerHorizontal="true"        android:layout_marginTop="124dp"        android:id="@+id/progressBarLoadMore" />    <TextView        android:text="@string/loadMore"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerVertical="true"        android:layout_below="@+id/progressBarLoadMore"        android:layout_marginTop="30dp"        android:textSize="24sp"        android:layout_centerHorizontal="true"        android:id="@+id/textView2" /></RelativeLayout>

寫完之后大概長(zhǎng)這個(gè)樣子,當(dāng)然你可以根據(jù)自己的喜好去定制

     原來(lái)的Gallery控件肯定不能實(shí)現(xiàn)我們想要的效果,所以下面我們來(lái)定制自己的Gallery,對(duì)原來(lái)的Galley稍稍動(dòng)一些手腳改造一下。接著上代碼:

public class MyGallery extends Gallery implements android.widget.AdapterView.OnItemSelectedListener{    private IGalleryEventListener mIGalleryEventListener; // 監(jiān)聽(tīng)Gallery滑動(dòng)    private View refreshView ; // 刷新的緩沖界面    private View loadMoreView ; // 加載更多緩沖的界面    private int startIndex = 0 ; // 記錄首項(xiàng)的索引    private int endIndex = 0 ; // 記錄最后一項(xiàng)的索引    public MyGallery(Context context) {        super(context);        this.setOnItemSelectedListener(this); // 設(shè)置監(jiān)聽(tīng)器    }    public MyGallery(Context context, AttributeSet attrs) {        super(context, attrs);        this.setOnItemSelectedListener(this); // 設(shè)置監(jiān)聽(tīng)器    }    public MyGallery(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        this.setOnItemSelectedListener(this); // 設(shè)置監(jiān)聽(tīng)器    }    /**     * 對(duì)外提供設(shè)置監(jiān)聽(tīng)器的方法     * @param iGalleryEventListener Gallery的滑動(dòng)監(jiān)聽(tīng)器     */    public void setGalleryEventListerner(IGalleryEventListener iGalleryEventListener){        this.mIGalleryEventListener = iGalleryEventListener;    }    /**     * 刷新或加載結(jié)束的回調(diào)方法     */    public void onCompleted(){        if(refreshView != null && refreshView.isShown()){            refreshView.setVisibility(View.GONE); // 刷新頁(yè)面不可見(jiàn)            this.setSelection(startIndex+1); // 選中刷新頁(yè)面的后一項(xiàng)        }        if(loadMoreView != null && loadMoreView.isShown()){            loadMoreView.setVisibility(View.GONE); // 加載更多頁(yè)面不可見(jiàn)            if(this.getChildAt(endIndex) != null ) this.setSelection(endIndex) ; // 有數(shù)據(jù)就選中剛剛加載的一項(xiàng)            else this.setSelection(endIndex-1); // 否則就選中加載更多頁(yè)面的前面一項(xiàng)        }    }    @Override    public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {        startIndex = 0 ; // 首項(xiàng)        endIndex = adapterView.getCount() - 1 ; // 最后一項(xiàng)        if(position == startIndex ){ // 表示滑動(dòng)到了最前面一頁(yè),刷新操作            refreshView = view ; // 刷新頁(yè)面保存            if(!refreshView.isShown()) refreshView.setVisibility(View.VISIBLE);            mIGalleryEventListener.onRefresh(); // 回調(diào)刷新的方法        }        if(position == endIndex){ // 表示滑動(dòng)到了最后一頁(yè),加載操作            loadMoreView = view ;            if(!loadMoreView.isShown()) loadMoreView.setVisibility(View.VISIBLE);            mIGalleryEventListener.onLoadMore(); // 回調(diào)加載的方法        }    }    @Override    public void onNothingSelected(AdapterView<?> adapterView) {    }}注釋已經(jīng)寫得很清楚了,紅色部分是我們自己定義的一個(gè)接口,有兩個(gè)待實(shí)現(xiàn)的方法(加載更多和刷新),紅色部分的方法給當(dāng)前的Gallery提供設(shè)置這個(gè)接口的方法,后面要用到。藍(lán)色部分是結(jié)束時(shí)候的回調(diào)方法,紫色部分是當(dāng)前的Gallery實(shí)現(xiàn)了OnItemSelectedListener接口的一些處理,當(dāng)滑動(dòng)到最前面一頁(yè)的時(shí)候讓刷新界面出現(xiàn),當(dāng)滑動(dòng)到最后一頁(yè)的時(shí)候讓加載更多的界面出現(xiàn)

public interface IGalleryEventListener {    public void onLoadMore(); // 加載更多的回調(diào)函數(shù)    public void onRefresh(); // 刷新的回調(diào)函數(shù)}上面是監(jiān)聽(tīng)的接口,包含兩個(gè)待實(shí)現(xiàn)的方法,后面再要使用的地方實(shí)現(xiàn)該接口即可。下面寫一下Gallery的適配器

public class MyGalleryAdapter extends BaseAdapter {    private Context mContext ; // 運(yùn)行的上下文    private List<PictureBean> mPictureList ; // 實(shí)體類數(shù)據(jù)集合    private LayoutInflater mInfalter ; //  界面渲染器    private View refreshView, loadMoreView; // 一頭一尾    public MyGalleryAdapter(){    }    /**     * 構(gòu)造方法     * @param context 上下文     * @param pictureList  實(shí)體類數(shù)據(jù)集合     */    public MyGalleryAdapter(Context context , List<PictureBean> pictureList){        this.mContext = context ;        this.mPictureList = pictureList ;    }    @Override    public int getCount() {        return mPictureList.size() + 2; // 這里多加了兩個(gè)是因?yàn)槲覀兌嗉恿藘蓚€(gè)界面,分別是加載和刷新的界面,在數(shù)據(jù)集合中一頭一尾    }    @Override    public PictureBean getItem(int position) {        if(position==0 || position== getCount()-1) return null;        return mPictureList.get(position-1) ;    }    @Override    public long getItemId(int i) {        return i;    }    @Override    public View getView(int position, View view, ViewGroup viewGroup) {        mInfalter = LayoutInflater.from(mContext);        if(position == 0 ){ // 第一頁(yè)            refreshView = mInfalter.inflate(R.layout.refresh_layout ,null);            refreshView.setVisibility(View.GONE); // 默認(rèn)設(shè)置刷新頁(yè)面不可見(jiàn)            return refreshView; // 返回刷新頁(yè)面        }else if(position == this.getCount() - 1){ //  最后一頁(yè)            loadMoreView = mInfalter.inflate(R.layout.loadmore_layout ,null);            loadMoreView.setVisibility(View.GONE); // 默認(rèn)設(shè)置加載更多不可見(jiàn)            return loadMoreView; // 返回加載更多頁(yè)面        }else{            if(view == null) view = mInfalter.inflate(R.layout.content_layout, null);            ImageView imageView = ViewHolder.get(view,R.id.image);            TextView describeTv = ViewHolder.get(view,R.id.describeTv);            imageView.setImageResource(getItem(position).getPictureResId()); // 設(shè)置相片資源ID            describeTv.setText(getItem(position).getPictureName());  // 設(shè)置相片名稱            return view ; // 返回內(nèi)容頁(yè)面        }    }}

上面代碼注意紅色加粗的部分,在原來(lái)的數(shù)據(jù)集合長(zhǎng)度上在加上2,表示一頭一尾各加了一個(gè)布局占位。

藍(lán)色部分也很好理解,初始的時(shí)候讓一頭一尾的兩個(gè)界面都隱藏起來(lái),該顯示的時(shí)候才讓其顯示。

這里有一個(gè)R.layout.content_layout的布局,如下,包含一個(gè)ImageView和一個(gè)TextView

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:padding="10dp"    android:gravity="center">    <TextView        android:id="@+id/describeTv"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_below="@+id/image"        android:layout_centerHorizontal="true"        android:layout_marginTop="20dp"        android:text="TextView"        android:textSize="24sp" />    <ImageView        android:id="@+id/image"        android:layout_width="300dp"        android:layout_height="360dp"        android:src="@mipmap/ic_launcher"        android:layout_centerInParent="true" /></RelativeLayout>

下面開始看MainActivity的布局界面

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/activity_main"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context="com.cjt.galleryrefreshdemo.MainActivity">    <com.cjt.galleryrefreshdemo.view.MyGallery        android:id="@+id/myGallery"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:spacing="15dp"        android:layout_alignParentTop="true"        android:layout_alignParentRight="true"        android:layout_alignParentEnd="true"        android:layout_marginRight="17dp"        android:layout_marginEnd="17dp">    </com.cjt.galleryrefreshdemo.view.MyGallery></RelativeLayout>這里使用的是我們剛剛自定義的Gallery布局,那么MainActivity要使用刷新和加載的功能,就不得不實(shí)現(xiàn)我們剛剛定義的接口了,代碼如下

public class MainActivity extends AppCompatActivity implements IGalleryEventListener{    private MyGallery myGallery ; // 自定義Gallery控件    private MyGalleryAdapter myGalleryAdapter ; // 適配器    private List<PictureBean> pictureList = new ArrayList<>();  // 數(shù)據(jù)集合,使用前要先轉(zhuǎn)換為L(zhǎng)ist的子類    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        myGallery = (MyGallery) findViewById(R.id.myGallery); /// 獲取界面自定義的Gallery控件        myGallery.setGalleryEventListerner(this); // 為Gallery設(shè)置滑動(dòng)監(jiān)聽(tīng)器        // 準(zhǔn)備數(shù)據(jù)        PictureBean bean ;        for (int i = 1; i <= 7 ; i++) {            bean = new PictureBean();            // 下面一句是獲取mipmap中對(duì)應(yīng)的圖片名稱的資源ID            int picResId = this.getResources().getIdentifier("pic"+i,"mipmap",getPackageName());            bean.setPictureResId(picResId);            bean.setPictureName("照片--"+i);            pictureList.add(bean);        }        // 設(shè)置適配器        myGalleryAdapter = new MyGalleryAdapter(this,pictureList) ;        myGallery.setAdapter(myGalleryAdapter);        myGallery.setSelection(1);   // 默認(rèn)選中第一項(xiàng),跳過(guò)第0項(xiàng)    }    @Override    public void onLoadMore() {        // 在這里處理加載更多的事件        taskThread(0);    }    @Override    public void onRefresh() {       // 在這里處理刷新的事件        taskThread(1);    }    /**     * 一般新開一個(gè)線程用于加載或刷新操作     * @param type  這里的type用于區(qū)分是刷新還是加載操作     */    private void taskThread(final int type){        new Thread(new Runnable() {            @Override            public void run() {                try {                    Thread.sleep(2000);                } catch (InterruptedException e) {                    e.printStackTrace();                }                Log.e("CJT","這里可以新建加載或刷新的任務(wù)");                getLoad(type); // 這里是模擬加載更多的任務(wù)            }        }).start();    }    // 模擬獲取數(shù)據(jù)的方法,這里一般是網(wǎng)絡(luò)請(qǐng)求加載數(shù)據(jù)    private void getLoad(int type){        if(type == 0){ // 加載操作            mHandler.sendEmptyMessage(0x01); // 加載完畢之后,發(fā)送消息,更新界面            // 這里模擬加載更多數(shù)據(jù)            // 準(zhǔn)備數(shù)據(jù)            PictureBean bean ;            for (int i = 1; i <= 4 ; i++) {                bean = new PictureBean();                int picResId = this.getResources().getIdentifier("m"+i,"mipmap",getPackageName());                bean.setPictureResId(picResId);                bean.setPictureName("美女--"+i);                pictureList.add(bean);            }        }else{            mHandler.sendEmptyMessage(0x02); // 刷新完畢之后,發(fā)送消息,更新界面        }    }    // 一般使用Handler來(lái)更新界面    private Handler mHandler = new Handler(){        @Override        public void handleMessage(Message msg) {            if(msg.what == 0x01){                // 更新界面                if(myGalleryAdapter != null )                    myGalleryAdapter.notifyDataSetChanged();            }else  if(msg.what == 0x02){                // 更新界面            }            myGallery.onCompleted(); // 同時(shí)調(diào)用加載結(jié)束的回調(diào)函數(shù),停止轉(zhuǎn)圈圈        }    };}首先實(shí)現(xiàn)了我們自定義的接口,并且重寫了兩個(gè)方法(刷新和加載),在刷新和加載中我們開啟了一個(gè)新的線程,模擬在后臺(tái)實(shí)現(xiàn)的網(wǎng)絡(luò)請(qǐng)求過(guò)程,加入線程休眠Thread.sleep(2000)主要是讓刷新界面或者加載界面都能出來(lái)露個(gè)臉,就是讓圈圈出來(lái)轉(zhuǎn)一下。getLoad()方法就是模擬我們的后臺(tái)請(qǐng)求數(shù)據(jù),我這里使用一個(gè)int類型用來(lái)區(qū)分是刷新請(qǐng)求還是加載更多的請(qǐng)求,當(dāng)然你們可以根據(jù)自己的需要去增加相應(yīng)的請(qǐng)求的參數(shù),比如分頁(yè)加載需要頁(yè)碼(pageNum)等。推薦使用Handler來(lái)更新界面,如果是加載更多的話,只需要調(diào)用Adapter的notifyDataSetChanged()方法,如果是刷新的話根據(jù)業(yè)務(wù)需求來(lái)更新,比如我是將數(shù)據(jù)集合清空,然后在填充一次,這樣避免了數(shù)據(jù)重復(fù)。最后別忘了回調(diào)加載結(jié)束的方法,不然那個(gè)刷新或加載更多的圈圈會(huì)一直不停的轉(zhuǎn)、不停的轉(zhuǎn)、不停的轉(zhuǎn)……。

這里有一個(gè)測(cè)試用的實(shí)體類,也一并貼上來(lái),顯得文章長(zhǎng)一些…………

public class PictureBean {    private int pictureResId ; // 圖片資源的ID    private String pictureName ; // 圖片的名稱描述    public int getPictureResId() {        return pictureResId;    }    public void setPictureResId(int pictureResId) {        this.pictureResId = pictureResId;    }    public String getPictureName() {        return pictureName;    }    public void setPictureName(String pictureName) {        this.pictureName = pictureName;    }    @Override    public String toString() {        return "PictureBean{" +                "pictureResId=" + pictureResId +                ", pictureName='" + pictureName + '/'' +                '}';    }}好像也沒(méi)見(jiàn)得有多長(zhǎng)。

總結(jié)一下:其實(shí)實(shí)現(xiàn)可滑動(dòng)控件的刷新或加載也不難,定義好接口以及相應(yīng)的待實(shí)現(xiàn)的方法,在要使用的地方實(shí)現(xiàn)該接口,并填充方法,在方法里面做刷新或加載的操作。另外刷新或加載完了之后,推薦使用Handler來(lái)更新界面,至于轉(zhuǎn)圈圈的界面,控制好時(shí)機(jī),該出現(xiàn)的時(shí)候讓他出現(xiàn),不該出現(xiàn)的時(shí)候堅(jiān)決將他干掉就行了。

參考: 感謝網(wǎng)上的資料,下次記得把鏈接和名字一并奉上,這次就低調(diào)些大笑

想要源碼的可以去這兩個(gè)地方,不要分,拿走不謝。我也是個(gè)菜鳥,希望跟大家共同探討人生,哈哈哈得意。

Git地址:https://github.com/1989Jiangtao/GalleryRefresh

代碼下載:http://download.csdn.net/detail/u010898329/9750269


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 大石桥市| 岑巩县| 山丹县| 江北区| 神池县| 平陆县| 富川| 深泽县| 吴江市| 扎赉特旗| 兴安盟| 建宁县| 开江县| 手游| 东台市| 怀化市| 磴口县| 中山市| 徐水县| 平潭县| 辰溪县| 句容市| 延寿县| 左云县| 府谷县| 蒲江县| 新干县| 鹤岗市| 南华县| 石门县| 响水县| 珠海市| 涞水县| 仁寿县| 建阳市| 哈尔滨市| 玉山县| 临安市| 文山县| 河东区| 新泰市|