Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android中如何實現多行、水平滾動的分頁的Gridview?

Android中如何實現多行、水平滾動的分頁的Gridview?

編輯:關於Android編程

功能要求:

(1)比如每頁顯示2X2,總共2XN,每個item顯示圖片+文字(點擊有鏈接)。

如果單行水平滾動,可以用Horizontalscrollview實現。

如果是多行水平滾動,則結合Gridview(一般是垂直滾動的)和Horizontalscrollview實現。

(2)水平滾動翻頁,下面有顯示當前頁的icon。

 

 

1.      實現自定義的HorizontalScrollView(HorizontalScrollView.java):

因為要翻頁時需要傳當前頁給調用者,所以fling函數中自己實現而不要調用父類的fling。


[java]  public class DrawerHScrollView extends HorizontalScrollView { 
    private static final String TAG = "DrawerHScrollView"; 
     
    private IDrawerPresenter drawerPresenter = null; 
    private int currentPage = 0; 
    private int totalPages = 1; 
    private static Hashtable<Integer, Integer> positionLeftTopOfPages = new Hashtable(); 
 
    public DrawerHScrollView(Context context) { 
        super(context); 
    } 
 
    public DrawerHScrollView(Context context, AttributeSet attrs) { 
        super(context, attrs); 
    } 
 
    public DrawerHScrollView(Context context, AttributeSet attrs, int defStyle) { 
        super(context, attrs, defStyle); 
    } 
     
    public void cleanup(){ 
        currentPage = 0; 
        totalPages = 1; 
        drawerPresenter = null; 
        if(positionLeftTopOfPages != null){ 
            positionLeftTopOfPages.clear(); 
        } 
    } 
     
    public void setParameters(int totalPages, int currentPage, int scrollDisX) { 
        Log.d(TAG, "~~~~~setParameters totalPages:"+totalPages +",currentPage:"+ currentPage +",scrollDisX:"+scrollDisX); 
        this.totalPages = totalPages; 
        this.currentPage = currentPage; 
        positionLeftTopOfPages.clear(); 
        for (int i = 0;i<totalPages;i++){ 
            int posx = (scrollDisX) * i; 
            positionLeftTopOfPages.put(i, posx); 
            Log.d(TAG, "~~~~~setParameters i:"+i +",posx:"+posx); 
        } 
        smoothScrollTo(0, 0); 
    } 
     
    public void setPresenter(IDrawerPresenter drawerPresenter ) { 
        this.drawerPresenter = drawerPresenter; 
    } 
     
    @Override 
    public void fling(int velocityX) { 
        Log.v(TAG, "-->fling velocityX:"+velocityX); 
        boolean change_flag = false; 
        if (velocityX > 0 && (currentPage < totalPages - 1)){ 
            currentPage++; 
            change_flag = true; 
        } else if (velocityX < 0 && (currentPage > 0)){ 
            currentPage--; 
            change_flag = true; 
        } 
        if (change_flag){ 
            int postionTo = (Integer)positionLeftTopOfPages.get(new Integer(currentPage)).intValue(); 
            Log.v(TAG, "------smoothScrollTo posx:"+postionTo); 
            smoothScrollTo(postionTo, 0); 
            drawerPresenter.dispatchEvent(totalPages, currentPage); 
        } 
        //super.fling(velocityX);  
    } 

public class DrawerHScrollView extends HorizontalScrollView {
 private static final String TAG = "DrawerHScrollView";
 
 private IDrawerPresenter drawerPresenter = null;
 private int currentPage = 0;
 private int totalPages = 1;
 private static Hashtable<Integer, Integer> positionLeftTopOfPages = new Hashtable();

 public DrawerHScrollView(Context context) {
  super(context);
 }

 public DrawerHScrollView(Context context, AttributeSet attrs) {
  super(context, attrs);
 }

 public DrawerHScrollView(Context context, AttributeSet attrs, int defStyle) {
  super(context, attrs, defStyle);
 }
 
 public void cleanup(){
  currentPage = 0;
  totalPages = 1;
  drawerPresenter = null;
  if(positionLeftTopOfPages != null){
   positionLeftTopOfPages.clear();
  }
 }
 
 public void setParameters(int totalPages, int currentPage, int scrollDisX) {
  Log.d(TAG, "~~~~~setParameters totalPages:"+totalPages +",currentPage:"+ currentPage +",scrollDisX:"+scrollDisX);
  this.totalPages = totalPages;
  this.currentPage = currentPage;
  positionLeftTopOfPages.clear();
  for (int i = 0;i<totalPages;i++){
   int posx = (scrollDisX) * i;
   positionLeftTopOfPages.put(i, posx);
   Log.d(TAG, "~~~~~setParameters i:"+i +",posx:"+posx);
  }
  smoothScrollTo(0, 0);
 }
 
 public void setPresenter(IDrawerPresenter drawerPresenter ) {
  this.drawerPresenter = drawerPresenter;
 }
 
 @Override
 public void fling(int velocityX) {
  Log.v(TAG, "-->fling velocityX:"+velocityX);
  boolean change_flag = false;
  if (velocityX > 0 && (currentPage < totalPages - 1)){
   currentPage++;
   change_flag = true;
  } else if (velocityX < 0 && (currentPage > 0)){
   currentPage--;
   change_flag = true;
  }
  if (change_flag){
   int postionTo = (Integer)positionLeftTopOfPages.get(new Integer(currentPage)).intValue();
   Log.v(TAG, "------smoothScrollTo posx:"+postionTo);
   smoothScrollTo(postionTo, 0);
   drawerPresenter.dispatchEvent(totalPages, currentPage);
  }
  //super.fling(velocityX);
 }
}


 

2.      布局文件Activity_main.xml:

 


[html]
<com.example.multilinegridview.DrawerHScrollView 
     android:id="@+id/hscrollview" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_margin="10dp" 
     android:scrollbars="none" 
     android:layout_below="@id/layout_drawer_top" 
     android:layout_above="@id/layout_pagenumber" 
     android:background="#CCCCCC" > 
     <LinearLayout 
         android:layout_width="fill_parent" 
         android:layout_height="wrap_content" 
         android:orientation="horizontal" > 
         <GridView 
             android:id="@+id/gridView" 
             android:layout_width="fill_parent" 
             android:layout_height="wrap_content" /> 
     </LinearLayout> 
 </com.example.multilinegridview.DrawerHScrollView> 

       <com.example.multilinegridview.DrawerHScrollView
            android:id="@+id/hscrollview"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:scrollbars="none"
            android:layout_below="@id/layout_drawer_top"
            android:layout_above="@id/layout_pagenumber"
            android:background="#CCCCCC" >
            <LinearLayout
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal" >
                <GridView
                    android:id="@+id/gridView"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content" />
            </LinearLayout>
        </com.example.multilinegridview.DrawerHScrollView>


 

3.      IDrawerPresenter接口(IDrawerPresenter.java):


[java]
public interface IDrawerPresenter { 
    IDrawerPresenter getInstance(); 
    void dispatchEvent(int totalPages, int currentPage); 

public interface IDrawerPresenter {
 IDrawerPresenter getInstance();
 void dispatchEvent(int totalPages, int currentPage);
}

 

4.      DrawerItem

 

[html]
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/layout_item" 
    android:orientation="vertical" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:gravity="center" 
    android:layout_gravity="center" 
    android:background="#FFFFFF"> 
    <ImageView    
        android:id="@+id/ivIcon"   
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:src="@drawable/ic_launcher"  /> 
    <TextView    
            android:id="@+id/tvTitle"   
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:text="優惠券1" 
            android:textColor="#000000" 
            android:textStyle="bold"/> 
</LinearLayout>  

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layout_item"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:layout_gravity="center"
    android:background="#FFFFFF">
    <ImageView  
        android:id="@+id/ivIcon" 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_launcher"  />
    <TextView  
            android:id="@+id/tvTitle" 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="優惠券1"
            android:textColor="#000000"
            android:textStyle="bold"/>
</LinearLayout>


5.      MainActivity.java

(1)實現IDrawerPresenter接口,在HorizontalScrollView裡通過IDrawerPresenter接口來返回當前頁,從而更新pageindicator。

[java]
  @Override 
public IDrawerPresenter getInstance() { 
    return this; 

 
@Override 
public void dispatchEvent(int totalPages, int currentPage) { 
    Log.v(TAG, "~~~~dispatchEvent currentPage:" + currentPage); 
    Message msg = Message.obtain(); 
    msg.what = MSG_DRAWER_UPDATE_PAGE_LAYOUT; 
    msg.arg1 = totalPages; 
    msg.arg2 = currentPage; 
    handler.sendMessage(msg); 

     @Override
 public IDrawerPresenter getInstance() {
  return this;
 }

 @Override
 public void dispatchEvent(int totalPages, int currentPage) {
  Log.v(TAG, "~~~~dispatchEvent currentPage:" + currentPage);
  Message msg = Message.obtain();
  msg.what = MSG_DRAWER_UPDATE_PAGE_LAYOUT;
  msg.arg1 = totalPages;
  msg.arg2 = currentPage;
  handler.sendMessage(msg);
 }

(2)PageItemImageView和page indicator的更新

PageItemImageView顯示normal的page indicator,之後再將當前頁的圖片換成selected。

[java]
   protected class PageItemImageView extends ImageView { 
public PageItemImageView(Context context) { 
    super(context); 
    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), 
            R.drawable.icon_page_normal); 
    this.setImageBitmap(bitmap); 

 
   public void updateDrawerPageLayout(int total_pages, int sel_page) { 
Log.e(TAG, "~~~updateBooksPageLayout total_pages:"+total_pages+",sel_page:"+sel_page); 
layout_pagenumber.removeAllViews(); 
if (total_pages <= 0 || sel_page < 0 || sel_page >= total_pages){ 
    Log.e(TAG, "total_pages or sel_page is outofrange."); 
    return; 

for (int i = 0;i< total_pages;i++){ 
    if (i != 0){ 
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); 
        params.setMargins(5, 0, 0, 0); 
        layout_pagenumber.addView(new PageItemImageView(this), params); 
    } else { 
        layout_pagenumber.addView(new PageItemImageView(this)); 
    } 

PageItemImageView selItem = (PageItemImageView) layout_pagenumber.getChildAt(sel_page); 
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon_page_selected); 
selItem.setImageBitmap(bitmap); 

     protected class PageItemImageView extends ImageView {
  public PageItemImageView(Context context) {
   super(context);
   Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
     R.drawable.icon_page_normal);
   this.setImageBitmap(bitmap);
  }
 }
     public void updateDrawerPageLayout(int total_pages, int sel_page) {
  Log.e(TAG, "~~~updateBooksPageLayout total_pages:"+total_pages+",sel_page:"+sel_page);
  layout_pagenumber.removeAllViews();
  if (total_pages <= 0 || sel_page < 0 || sel_page >= total_pages){
   Log.e(TAG, "total_pages or sel_page is outofrange.");
   return;
  }
  for (int i = 0;i< total_pages;i++){
   if (i != 0){
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    params.setMargins(5, 0, 0, 0);
    layout_pagenumber.addView(new PageItemImageView(this), params);
   } else {
    layout_pagenumber.addView(new PageItemImageView(this));
   }
  }
  PageItemImageView selItem = (PageItemImageView) layout_pagenumber.getChildAt(sel_page);
  Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon_page_selected);
  selItem.setImageBitmap(bitmap);
 }
(3)DrawerListAdapter

[java]
private class DrawerListAdapter extends BaseAdapter { 
    private final String TAG = "MyListAdapter"; 
    private LayoutInflater mInflater; 
    private LinearLayout layout_item; 
    private TextView tvTitle; 
    private ImageView ivIcon; 
    private final Context context; 
    private int colWid; 
    private int colHei; 
 
    public DrawerListAdapter(Context context, int colWid, int colHei) { 
        this.context = context; 
        this.colWid = colWid; 
        this.colHei = colHei; 
        mInflater = (LayoutInflater) context 
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    } 
 
    public int getCount() { 
        return drawerItemList.size(); 
    } 
 
    public Object getItem(int position) { 
        return drawerItemList.get(position); 
    } 
 
    public long getItemId(int position) { 
        return position; 
    } 
 
    public View getView(int position, View convertView, ViewGroup parent) { 
        DrawerItem item = drawerItemList.get(position); 
        if (convertView == null) { 
            convertView = mInflater.inflate(R.layout.drawer_item, null); 
            layout_item = (LinearLayout) convertView 
                    .findViewById(R.id.layout_item); 
            ivIcon = (ImageView) convertView.findViewById(R.id.ivIcon); 
            tvTitle = (TextView) convertView.findViewById(R.id.tvTitle); 
            if (colHei != 0 && colWid != 0) { 
                LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( 
                        colWid, colHei - 30); 
                ivIcon.setLayoutParams(params); 
            } 
            convertView.setTag(layout_item); 
        } else { 
            layout_item = (LinearLayout) convertView.getTag(); 
        } 
        ivIcon.setImageResource(R.drawable.ic_launcher); 
        tvTitle.setText(String.valueOf(position)); 
        return convertView; 
    } 

 private class DrawerListAdapter extends BaseAdapter {
  private final String TAG = "MyListAdapter";
  private LayoutInflater mInflater;
  private LinearLayout layout_item;
  private TextView tvTitle;
  private ImageView ivIcon;
  private final Context context;
  private int colWid;
  private int colHei;

  public DrawerListAdapter(Context context, int colWid, int colHei) {
   this.context = context;
   this.colWid = colWid;
   this.colHei = colHei;
   mInflater = (LayoutInflater) context
     .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  }

  public int getCount() {
   return drawerItemList.size();
  }

  public Object getItem(int position) {
   return drawerItemList.get(position);
  }

  public long getItemId(int position) {
   return position;
  }

  public View getView(int position, View convertView, ViewGroup parent) {
   DrawerItem item = drawerItemList.get(position);
   if (convertView == null) {
    convertView = mInflater.inflate(R.layout.drawer_item, null);
    layout_item = (LinearLayout) convertView
      .findViewById(R.id.layout_item);
    ivIcon = (ImageView) convertView.findViewById(R.id.ivIcon);
    tvTitle = (TextView) convertView.findViewById(R.id.tvTitle);
    if (colHei != 0 && colWid != 0) {
     LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
       colWid, colHei - 30);
     ivIcon.setLayoutParams(params);
    }
    convertView.setTag(layout_item);
   } else {
    layout_item = (LinearLayout) convertView.getTag();
   }
   ivIcon.setImageResource(R.drawable.ic_launcher);
   tvTitle.setText(String.valueOf(position));
   return convertView;
  }
 }


(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]
public void updateDrawerLayout() { 
    if ((drawerItemList == null) || (drawerItemList.size() == 0)) { 
        Log.d(TAG, "itemList is null or empty"); 
        return; 
    } 
    if (!hasMeasured){ 
        Log.d(TAG, "hasMeasured is false"); 
        return; 
    } 
    int scrollWid = hscrollview.getWidth(); 
    int scrollHei = hscrollview.getHeight(); 
    if (scrollWid <= 0 || scrollHei <= 0){ 
        Log.d(TAG, "scrollWid or scrollHei is less than 0"); 
        return; 
    } 
     
    int spaceing = 10; 
    int colWid = (scrollWid - spaceing * 3) / 2; 
    int colHei = (scrollHei - spaceing * 3) / 2; 
    int numCols = (drawerItemList.size() - 1) / 2 + 1; 
    int gridViewWid = numCols * colWid + (numCols + 1) * spaceing; 
    // if numCols is odd (like 5), add blank space  
    if (numCols % 2 == 1){ 
        gridViewWid += colWid + spaceing; 
    } 
     
    LayoutParams params = new LayoutParams(gridViewWid, scrollHei); 
    gridView.setLayoutParams(params); 
    gridView.setColumnWidth(colWid); 
    gridView.setHorizontalSpacing(spaceing); 
    gridView.setVerticalSpacing(spaceing); 
    gridView.setStretchMode(GridView.NO_STRETCH); 
    gridView.setNumColumns(numCols); 
 
    adapter = new DrawerListAdapter(this, colWid, colHei); 
    listener = new DrawerItemClickListener(); 
    gridView.setAdapter(adapter); 
    gridView.setOnItemClickListener(listener); 
 
    int pageNum = (drawerItemList.size() - 1) / 4 + 1; 
    hscrollview.setParameters(pageNum, 0, scrollWid - spaceing); 
    updateDrawerPageLayout(pageNum, 0); 

 public void updateDrawerLayout() {
  if ((drawerItemList == null) || (drawerItemList.size() == 0)) {
   Log.d(TAG, "itemList is null or empty");
   return;
  }
  if (!hasMeasured){
   Log.d(TAG, "hasMeasured is false");
   return;
  }
  int scrollWid = hscrollview.getWidth();
  int scrollHei = hscrollview.getHeight();
  if (scrollWid <= 0 || scrollHei <= 0){
   Log.d(TAG, "scrollWid or scrollHei is less than 0");
   return;
  }
  
  int spaceing = 10;
  int colWid = (scrollWid - spaceing * 3) / 2;
  int colHei = (scrollHei - spaceing * 3) / 2;
  int numCols = (drawerItemList.size() - 1) / 2 + 1;
  int gridViewWid = numCols * colWid + (numCols + 1) * spaceing;
  // if numCols is odd (like 5), add blank space
  if (numCols % 2 == 1){
   gridViewWid += colWid + spaceing;
  }
  
  LayoutParams params = new LayoutParams(gridViewWid, scrollHei);
  gridView.setLayoutParams(params);
  gridView.setColumnWidth(colWid);
  gridView.setHorizontalSpacing(spaceing);
  gridView.setVerticalSpacing(spaceing);
  gridView.setStretchMode(GridView.NO_STRETCH);
  gridView.setNumColumns(numCols);

  adapter = new DrawerListAdapter(this, colWid, colHei);
  listener = new DrawerItemClickListener();
  gridView.setAdapter(adapter);
  gridView.setOnItemClickListener(listener);

  int pageNum = (drawerItemList.size() - 1) / 4 + 1;
  hscrollview.setParameters(pageNum, 0, scrollWid - spaceing);
  updateDrawerPageLayout(pageNum, 0);
 }


效果圖:


 

\
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved