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. }  

 

效果图:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值