zoukankan      html  css  js  c++  java
  • Android中如何实现多行、水平滚动的分页的Gridview?

    功能要求:

    (1)比如每页显示2X2,总共2XN,每个item显示图片+文字(点击有链接)。

    如果单行水平滚动,可以用Horizontalscrollview实现。

    如果是多行水平滚动,则结合Gridview(一般是垂直滚动的)和Horizontalscrollview实现。

    (2)水平滚动翻页,下面有显示当前页的icon。

     

     

    1.      实现自定义的HorizontalScrollView(HorizontalScrollView.java):

    因为要翻页时需要传当前页给调用者,所以fling函数中自己实现而不要调用父类的fling。

     

    [java] view plaincopy
     
    1. public class DrawerHScrollView extends HorizontalScrollView {  
    2.     private static final String TAG = "DrawerHScrollView";  
    3.       
    4.     private IDrawerPresenter drawerPresenter = null;  
    5.     private int currentPage = 0;  
    6.     private int totalPages = 1;  
    7.     private static Hashtable<Integer, Integer> positionLeftTopOfPages = new Hashtable();  
    8.   
    9.     public DrawerHScrollView(Context context) {  
    10.         super(context);  
    11.     }  
    12.   
    13.     public DrawerHScrollView(Context context, AttributeSet attrs) {  
    14.         super(context, attrs);  
    15.     }  
    16.   
    17.     public DrawerHScrollView(Context context, AttributeSet attrs, int defStyle) {  
    18.         super(context, attrs, defStyle);  
    19.     }  
    20.       
    21.     public void cleanup(){  
    22.         currentPage = 0;  
    23.         totalPages = 1;  
    24.         drawerPresenter = null;  
    25.         if(positionLeftTopOfPages != null){  
    26.             positionLeftTopOfPages.clear();  
    27.         }  
    28.     }  
    29.       
    30.     public void setParameters(int totalPages, int currentPage, int scrollDisX) {  
    31.         Log.d(TAG, "~~~~~setParameters totalPages:"+totalPages +",currentPage:"+ currentPage +",scrollDisX:"+scrollDisX);  
    32.         this.totalPages = totalPages;  
    33.         this.currentPage = currentPage;  
    34.         positionLeftTopOfPages.clear();  
    35.         for (int i = 0;i<totalPages;i++){  
    36.             int posx = (scrollDisX) * i;  
    37.             positionLeftTopOfPages.put(i, posx);  
    38.             Log.d(TAG, "~~~~~setParameters i:"+i +",posx:"+posx);  
    39.         }  
    40.         smoothScrollTo(0, 0);  
    41.     }  
    42.       
    43.     public void setPresenter(IDrawerPresenter drawerPresenter ) {  
    44.         this.drawerPresenter = drawerPresenter;  
    45.     }  
    46.       
    47.     @Override  
    48.     public void fling(int velocityX) {  
    49.         Log.v(TAG, "-->fling velocityX:"+velocityX);  
    50.         boolean change_flag = false;  
    51.         if (velocityX > 0 && (currentPage < totalPages - 1)){  
    52.             currentPage++;  
    53.             change_flag = true;  
    54.         } else if (velocityX < 0 && (currentPage > 0)){  
    55.             currentPage--;  
    56.             change_flag = true;  
    57.         }  
    58.         if (change_flag){  
    59.             int postionTo = (Integer)positionLeftTopOfPages.get(new Integer(currentPage)).intValue();  
    60.             Log.v(TAG, "------smoothScrollTo posx:"+postionTo);  
    61.             smoothScrollTo(postionTo, 0);  
    62.             drawerPresenter.dispatchEvent(totalPages, currentPage);  
    63.         }  
    64.         //super.fling(velocityX);  
    65.     }  
    66. }  

     

     

    2.      布局文件Activity_main.xml:

     

    [html] view plaincopy
     
    1. <com.example.multilinegridview.DrawerHScrollView  
    2.      android:id="@+id/hscrollview"  
    3.      android:layout_width="match_parent"  
    4.      android:layout_height="wrap_content"  
    5.      android:layout_margin="10dp"  
    6.      android:scrollbars="none"  
    7.      android:layout_below="@id/layout_drawer_top"  
    8.      android:layout_above="@id/layout_pagenumber"  
    9.      android:background="#CCCCCC" >  
    10.      <LinearLayout  
    11.          android:layout_width="fill_parent"  
    12.          android:layout_height="wrap_content"  
    13.          android:orientation="horizontal" >  
    14.          <GridView  
    15.              android:id="@+id/gridView"  
    16.              android:layout_width="fill_parent"  
    17.              android:layout_height="wrap_content" />  
    18.      </LinearLayout>  
    19.  </com.example.multilinegridview.DrawerHScrollView>  

     

     

    3.      IDrawerPresenter接口(IDrawerPresenter.java):

     

    [java] view plaincopy
     
    1. public interface IDrawerPresenter {  
    2.     IDrawerPresenter getInstance();  
    3.     void dispatchEvent(int totalPages, int currentPage);  
    4. }  

     

     

    4.      DrawerItem

     

     

    [html] view plaincopy
     
    1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    2.     android:id="@+id/layout_item"  
    3.     android:orientation="vertical"  
    4.     android:layout_width="match_parent"  
    5.     android:layout_height="wrap_content"  
    6.     android:gravity="center"  
    7.     android:layout_gravity="center"  
    8.     android:background="#FFFFFF">  
    9.     <ImageView     
    10.         android:id="@+id/ivIcon"    
    11.         android:layout_width="wrap_content"  
    12.         android:layout_height="wrap_content"  
    13.         android:src="@drawable/ic_launcher"  />  
    14.     <TextView     
    15.             android:id="@+id/tvTitle"    
    16.             android:layout_width="wrap_content"  
    17.             android:layout_height="wrap_content"  
    18.             android:text="优惠券1"  
    19.             android:textColor="#000000"  
    20.             android:textStyle="bold"/>  
    21. </LinearLayout>   

     

    5.      MainActivity.java

    (1)实现IDrawerPresenter接口,在HorizontalScrollView里通过IDrawerPresenter接口来返回当前页,从而更新pageindicator。

    [java] view plaincopy
     
    1.     @Override  
    2. public IDrawerPresenter getInstance() {  
    3.     return this;  
    4. }  
    5.   
    6. @Override  
    7. public void dispatchEvent(int totalPages, int currentPage) {  
    8.     Log.v(TAG, "~~~~dispatchEvent currentPage:" + currentPage);  
    9.     Message msg = Message.obtain();  
    10.     msg.what = MSG_DRAWER_UPDATE_PAGE_LAYOUT;  
    11.     msg.arg1 = totalPages;  
    12.     msg.arg2 = currentPage;  
    13.     handler.sendMessage(msg);  
    14. }  

    (2)PageItemImageView和page indicator的更新

    PageItemImageView显示normal的page indicator,之后再将当前页的图片换成selected。

    [java] view plaincopy
     
    1.    protected class PageItemImageView extends ImageView {  
    2. public PageItemImageView(Context context) {  
    3.     super(context);  
    4.     Bitmap bitmap = BitmapFactory.decodeResource(getResources(),  
    5.             R.drawable.icon_page_normal);  
    6.     this.setImageBitmap(bitmap);  
    7. }  
    8.   
    9.    public void updateDrawerPageLayout(int total_pages, int sel_page) {  
    10. Log.e(TAG, "~~~updateBooksPageLayout total_pages:"+total_pages+",sel_page:"+sel_page);  
    11. layout_pagenumber.removeAllViews();  
    12. if (total_pages <= 0 || sel_page < 0 || sel_page >= total_pages){  
    13.     Log.e(TAG, "total_pages or sel_page is outofrange.");  
    14.     return;  
    15. }  
    16. for (int i = 0;i< total_pages;i++){  
    17.     if (i != 0){  
    18.         LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);  
    19.         params.setMargins(5, 0, 0, 0);  
    20.         layout_pagenumber.addView(new PageItemImageView(this), params);  
    21.     } else {  
    22.         layout_pagenumber.addView(new PageItemImageView(this));  
    23.     }  
    24. }  
    25. PageItemImageView selItem = (PageItemImageView) layout_pagenumber.getChildAt(sel_page);  
    26. Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon_page_selected);  
    27. selItem.setImageBitmap(bitmap);  


    (3)DrawerListAdapter

     

    [java] view plaincopy
     
    1. private class DrawerListAdapter extends BaseAdapter {  
    2.     private final String TAG = "MyListAdapter";  
    3.     private LayoutInflater mInflater;  
    4.     private LinearLayout layout_item;  
    5.     private TextView tvTitle;  
    6.     private ImageView ivIcon;  
    7.     private final Context context;  
    8.     private int colWid;  
    9.     private int colHei;  
    10.   
    11.     public DrawerListAdapter(Context context, int colWid, int colHei) {  
    12.         this.context = context;  
    13.         this.colWid = colWid;  
    14.         this.colHei = colHei;  
    15.         mInflater = (LayoutInflater) context  
    16.                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);  
    17.     }  
    18.   
    19.     public int getCount() {  
    20.         return drawerItemList.size();  
    21.     }  
    22.   
    23.     public Object getItem(int position) {  
    24.         return drawerItemList.get(position);  
    25.     }  
    26.   
    27.     public long getItemId(int position) {  
    28.         return position;  
    29.     }  
    30.   
    31.     public View getView(int position, View convertView, ViewGroup parent) {  
    32.         DrawerItem item = drawerItemList.get(position);  
    33.         if (convertView == null) {  
    34.             convertView = mInflater.inflate(R.layout.drawer_item, null);  
    35.             layout_item = (LinearLayout) convertView  
    36.                     .findViewById(R.id.layout_item);  
    37.             ivIcon = (ImageView) convertView.findViewById(R.id.ivIcon);  
    38.             tvTitle = (TextView) convertView.findViewById(R.id.tvTitle);  
    39.             if (colHei != 0 && colWid != 0) {  
    40.                 LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(  
    41.                         colWid, colHei - 30);  
    42.                 ivIcon.setLayoutParams(params);  
    43.             }  
    44.             convertView.setTag(layout_item);  
    45.         } else {  
    46.             layout_item = (LinearLayout) convertView.getTag();  
    47.         }  
    48.         ivIcon.setImageResource(R.drawable.ic_launcher);  
    49.         tvTitle.setText(String.valueOf(position));  
    50.         return convertView;  
    51.     }  
    52. }  

     

    (4)DrawerItemClickListener:

    实现OnItemClickListener。

     

    (5) updateDrawerLayout

    获得data的size后,可以算出列数来得到固定行。

                       intnumCols = (drawerItemList.size() - 1) / 2 + 1

    再算出gridview的width。因每页可显示2列,最后一页可能右侧没有,为了翻页顺滑,可以给gridview增加一列空白。

                       intgridViewWid = numCols * colWid + (numCols + 1) * spaceing;

                       if(numCols % 2 == 1){

                                gridViewWid+= colWid + spaceing;

                       }

    [java] view plaincopy
     
    1. public void updateDrawerLayout() {  
    2.     if ((drawerItemList == null) || (drawerItemList.size() == 0)) {  
    3.         Log.d(TAG, "itemList is null or empty");  
    4.         return;  
    5.     }  
    6.     if (!hasMeasured){  
    7.         Log.d(TAG, "hasMeasured is false");  
    8.         return;  
    9.     }  
    10.     int scrollWid = hscrollview.getWidth();  
    11.     int scrollHei = hscrollview.getHeight();  
    12.     if (scrollWid <= 0 || scrollHei <= 0){  
    13.         Log.d(TAG, "scrollWid or scrollHei is less than 0");  
    14.         return;  
    15.     }  
    16.       
    17.     int spaceing = 10;  
    18.     int colWid = (scrollWid - spaceing * 3) / 2;  
    19.     int colHei = (scrollHei - spaceing * 3) / 2;  
    20.     int numCols = (drawerItemList.size() - 1) / 2 + 1;  
    21.     int gridViewWid = numCols * colWid + (numCols + 1) * spaceing;  
    22.     // if numCols is odd (like 5), add blank space  
    23.     if (numCols % 2 == 1){  
    24.         gridViewWid += colWid + spaceing;  
    25.     }  
    26.       
    27.     LayoutParams params = new LayoutParams(gridViewWid, scrollHei);  
    28.     gridView.setLayoutParams(params);  
    29.     gridView.setColumnWidth(colWid);  
    30.     gridView.setHorizontalSpacing(spaceing);  
    31.     gridView.setVerticalSpacing(spaceing);  
    32.     gridView.setStretchMode(GridView.NO_STRETCH);  
    33.     gridView.setNumColumns(numCols);  
    34.   
    35.     adapter = new DrawerListAdapter(this, colWid, colHei);  
    36.     listener = new DrawerItemClickListener();  
    37.     gridView.setAdapter(adapter);  
    38.     gridView.setOnItemClickListener(listener);  
    39.   
    40.     int pageNum = (drawerItemList.size() - 1) / 4 + 1;  
    41.     hscrollview.setParameters(pageNum, 0, scrollWid - spaceing);  
    42.     updateDrawerPageLayout(pageNum, 0);  
    43. }  

     

    效果图:

  • 相关阅读:
    Jzoj4822 完美标号
    Jzoj4822 完美标号
    Jzoj4792 整除
    Jzoj4792 整除
    Educational Codeforces Round 79 A. New Year Garland
    Good Bye 2019 C. Make Good
    ?Good Bye 2019 B. Interesting Subarray
    Good Bye 2019 A. Card Game
    力扣算法题—088扰乱字符串【二叉树】
    力扣算法题—086分隔链表
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/4672858.html
Copyright © 2011-2022 走看看