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

首頁 > 學院 > 開發設計 > 正文

安卓之Gallery實現刷新加載和分頁加載

2019-11-09 18:56:52
字體:
來源:轉載
供稿:網友

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

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

 

下面開始正文。首先講一下實現的思路:Gallery是橫向滑動的控件,我們類似ListView實現刷新一樣,當滑動到第0項時候,開始刷新操作,滑動到最后一項的時候進行分頁加載的操作。

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

<?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>

寫完之后大概長這個樣子,當然你可以根據自己的喜好去定制

     原來的Gallery控件肯定不能實現我們想要的效果,所以下面我們來定制自己的Gallery,對原來的Galley稍稍動一些手腳改造一下。接著上代碼:

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

public interface IGalleryEventListener {    public void onLoadMore(); // 加載更多的回調函數    public void onRefresh(); // 刷新的回調函數}上面是監聽的接口,包含兩個待實現的方法,后面再要使用的地方實現該接口即可。下面寫一下Gallery的適配器

public class MyGalleryAdapter extends BaseAdapter {    private Context mContext ; // 運行的上下文    private List<PictureBean> mPictureList ; // 實體類數據集合    private LayoutInflater mInfalter ; //  界面渲染器    private View refreshView, loadMoreView; // 一頭一尾    public MyGalleryAdapter(){    }    /**     * 構造方法     * @param context 上下文     * @param pictureList  實體類數據集合     */    public MyGalleryAdapter(Context context , List<PictureBean> pictureList){        this.mContext = context ;        this.mPictureList = pictureList ;    }    @Override    public int getCount() {        return mPictureList.size() + 2; // 這里多加了兩個是因為我們多加了兩個界面,分別是加載和刷新的界面,在數據集合中一頭一尾    }    @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 ){ // 第一頁            refreshView = mInfalter.inflate(R.layout.refresh_layout ,null);            refreshView.setVisibility(View.GONE); // 默認設置刷新頁面不可見            return refreshView; // 返回刷新頁面        }else if(position == this.getCount() - 1){ //  最后一頁            loadMoreView = mInfalter.inflate(R.layout.loadmore_layout ,null);            loadMoreView.setVisibility(View.GONE); // 默認設置加載更多不可見            return loadMoreView; // 返回加載更多頁面        }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()); // 設置相片資源ID            describeTv.setText(getItem(position).getPictureName());  // 設置相片名稱            return view ; // 返回內容頁面        }    }}

上面代碼注意紅色加粗的部分,在原來的數據集合長度上在加上2,表示一頭一尾各加了一個布局占位。

藍色部分也很好理解,初始的時候讓一頭一尾的兩個界面都隱藏起來,該顯示的時候才讓其顯示。

這里有一個R.layout.content_layout的布局,如下,包含一個ImageView和一個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要使用刷新和加載的功能,就不得不實現我們剛剛定義的接口了,代碼如下

public class MainActivity extends AppCompatActivity implements IGalleryEventListener{    private MyGallery myGallery ; // 自定義Gallery控件    private MyGalleryAdapter myGalleryAdapter ; // 適配器    private List<PictureBean> pictureList = new ArrayList<>();  // 數據集合,使用前要先轉換為List的子類    @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設置滑動監聽器        // 準備數據        PictureBean bean ;        for (int i = 1; i <= 7 ; i++) {            bean = new PictureBean();            // 下面一句是獲取mipmap中對應的圖片名稱的資源ID            int picResId = this.getResources().getIdentifier("pic"+i,"mipmap",getPackageName());            bean.setPictureResId(picResId);            bean.setPictureName("照片--"+i);            pictureList.add(bean);        }        // 設置適配器        myGalleryAdapter = new MyGalleryAdapter(this,pictureList) ;        myGallery.setAdapter(myGalleryAdapter);        myGallery.setSelection(1);   // 默認選中第一項,跳過第0項    }    @Override    public void onLoadMore() {        // 在這里處理加載更多的事件        taskThread(0);    }    @Override    public void onRefresh() {       // 在這里處理刷新的事件        taskThread(1);    }    /**     * 一般新開一個線程用于加載或刷新操作     * @param type  這里的type用于區分是刷新還是加載操作     */    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","這里可以新建加載或刷新的任務");                getLoad(type); // 這里是模擬加載更多的任務            }        }).start();    }    // 模擬獲取數據的方法,這里一般是網絡請求加載數據    private void getLoad(int type){        if(type == 0){ // 加載操作            mHandler.sendEmptyMessage(0x01); // 加載完畢之后,發送消息,更新界面            // 這里模擬加載更多數據            // 準備數據            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); // 刷新完畢之后,發送消息,更新界面        }    }    // 一般使用Handler來更新界面    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(); // 同時調用加載結束的回調函數,停止轉圈圈        }    };}首先實現了我們自定義的接口,并且重寫了兩個方法(刷新和加載),在刷新和加載中我們開啟了一個新的線程,模擬在后臺實現的網絡請求過程,加入線程休眠Thread.sleep(2000)主要是讓刷新界面或者加載界面都能出來露個臉,就是讓圈圈出來轉一下。getLoad()方法就是模擬我們的后臺請求數據,我這里使用一個int類型用來區分是刷新請求還是加載更多的請求,當然你們可以根據自己的需要去增加相應的請求的參數,比如分頁加載需要頁碼(pageNum)等。推薦使用Handler來更新界面,如果是加載更多的話,只需要調用Adapter的notifyDataSetChanged()方法,如果是刷新的話根據業務需求來更新,比如我是將數據集合清空,然后在填充一次,這樣避免了數據重復。最后別忘了回調加載結束的方法,不然那個刷新或加載更多的圈圈會一直不停的轉、不停的轉、不停的轉……。

這里有一個測試用的實體類,也一并貼上來,顯得文章長一些…………

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 + '/'' +                '}';    }}好像也沒見得有多長。

總結一下:其實實現可滑動控件的刷新或加載也不難,定義好接口以及相應的待實現的方法,在要使用的地方實現該接口,并填充方法,在方法里面做刷新或加載的操作。另外刷新或加載完了之后,推薦使用Handler來更新界面,至于轉圈圈的界面,控制好時機,該出現的時候讓他出現,不該出現的時候堅決將他干掉就行了。

參考: 感謝網上的資料,下次記得把鏈接和名字一并奉上,這次就低調些大笑

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

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

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


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 嘉禾县| 长阳| 海城市| 观塘区| 台北市| 平江县| 汉沽区| 景谷| 堆龙德庆县| 平顺县| 宁安市| 获嘉县| 屏东县| 安仁县| 沙洋县| 隆子县| 阜平县| 敖汉旗| 体育| 德化县| 贵港市| 商丘市| 澄江县| 宜黄县| 女性| 保靖县| 蓬安县| 万州区| 苏尼特左旗| 修文县| 巫山县| 淅川县| 惠东县| 随州市| 义乌市| 饶阳县| 新丰县| 伊宁县| 青田县| 耒阳市| 峨山|