Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發實例 >> Android 分享機頂盒項目的封裝類《GridView》

Android 分享機頂盒項目的封裝類《GridView》

編輯:Android開發實例

  由於使用系統自帶的GridView 不夠靈活,不能允許拖拉控件,故自己結合LinearLayout 封裝的一個GridView ,通過本篇文章的閱讀你可以學會如何自定義控件,如何使用組合控件,如何為自己的組合控件添加數據源和如何為自定義控件添加屬性。

  首先,我們要實現的效果是這樣的:

  上面1 2也是一個封裝控件,用來為應用程序分頁,具體如何實現下篇文章會提到,本篇先講GridView。如圖,這是一個標准的800*480大小的屏幕,所以設置了一頁GridView 顯示的應用程序數據為 三行五列,不足五列則按需顯示。

  按照上面的圖例需求,大致上可以把GridView 畫成如下的方式:

 

  思路如下:

   默認將我們的組合控件設置為Orientation 是VERTICAL。  首先一行五個,那麼一行以一個Orientation 為HORIZONTAL 的線性布局包起來。然後在一行結束後,將Orientation  的線性布局添加進組合控件裡面來,不足五個則按需添加進來。

  實現這一效果我們需要兩個類,一個類用來表示GridView 的行,這裡我們起名為TableRow,代碼如下:

 

public class TableRow {
        private TableCell[] cell;

        public TableRow(TableCell[] cell) {
            this.cell = cell;
        }

        public int getSize() {
            return cell.length;
        }

        public TableCell getCellValue(int index) {
            if (index >= getSize()) {
                return null;
            }
            return cell[index];
        }

        public int getCellCount() {

            return cell.length;

        }

        public int getLastCellCount() {
            return lastRowCount;
        }
    }

 

 

  另外一個類用來表示GridView 每行的列個,這裡我們取名為TableCell,代碼如下:

 

static public class TableCell {
        private Object value;

        public TableCell(Object value) {
            this.value = value;
        }

        public Object getValue() {
            return value;
        }
    }

 

  並且我們還需要為GridView 設置一個外部可添加數據的方法,代碼如下:

 

public void setAdapter(AppsAdapter appsAdapter) {
        this.adapter = appsAdapter;
        this.setOrientation(LinearLayout.VERTICAL);
        bindView();
    }

 

 

其中,AppsAdapter 是一個自定義的BaseAdapter ,代碼很簡單,這裡就不列出來了。關鍵的還是要看bindView ,這個方法是本篇GridView 顯示數據的核心方法,代碼如下:

 

void bindView() {
        removeAllViews();
        int count = adapter.getCount();
        TableCell[] cell = null;
        int j = 0;
        LinearLayout layout;
        tableRowsList = new ArrayList<HashMap<String, Object>>();
        for (int i = 0; i < count; i++) {
            j++;
            final int position = i;
            if (j > getColumnCount() || i == 0) {
                cell = new TableCell[getColumnCount()];
            }

            final View view = adapter.getView(i, null, null);

            view.setOnTouchListener(new OnTouchListener() {

                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    // TODO Auto-generated method stub
                    unCheckPressed();
                    checkRowID = -1;
                    checkColumnID = -1;
                    if (onItemClickEvent != null) {

                        onItemClickEvent.onItemClick(position, event, view);
                    }
                    return false;
                }
            });

            view.setOnLongClickListener(new OnLongClickListener() {

                @Override
                public boolean onLongClick(View v) {
                    if (onLongPress != null) {
                        onLongPress.onLongPress(v);
                    }
                    return true;
                }
            });
            cell[j - 1] = new TableCell(view);
            if (j == getColumnCount()) {
                lastRowCount = j;
                j = 0;
                HashMap<String, Object> map = new HashMap<String, Object>();
                TableRow tr = new TableRow(cell);
                map.put("tableRow", tr);
                tableRowsList.add(map);
                layout = new LinearLayout(getContext());
                addLayout(layout, cell, tr.getSize(), tr);

            } else if (i >= count - 1 && j > 0) {
                lastRowCount = j;
                HashMap<String, Object> map = new HashMap<String, Object>();
                TableRow tr = new TableRow(cell);
                map.put("tableRow", tr);
                tableRowsList.add(map);
                layout = new LinearLayout(getContext());
                addLayout(layout, cell, j, tr);
            }

        }

    }

getColumnCount()是一個屬性,表示可以從xml或者從代碼動態改變GridView 每列顯示的個數,屬性點的代碼為如下:

 

public gridViewExt(Context context, AttributeSet attrs) {
        super(context, attrs);
        int resouceID = -1;
        TypedArray typedArray = context.obtainStyledAttributes(attrs,
                R.styleable.GridViewExt);
        int N = typedArray.getIndexCount();
        for (int i = 0; i < N; i++) {
            int attr = typedArray.getIndex(i);
            switch (attr) {
            case R.styleable.GridViewExt_ColumnCount:
                resouceID = typedArray.getInt(
                        R.styleable.GridViewExt_ColumnCount, 0);
                setColumnCount(resouceID);
                break;

            }
        }
        typedArray.recycle();
    }

 

當然,你必須在res 創建屬性xml ,這裡不多講,可以去我博客看看如何為 View 添加屬性

還有,還必須實現它的支持鍵盤的上下左右的焦點,下面的代碼將會提供該功能,但還必須配合Activity 的操作,等下文再講述。效果是這樣的:

該 類的全部源碼為:

 

GridViewExt package com.yaomei.widget;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import android.content.Context;
import android.content.Intent;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.yaomei.activity.adapter.AppsAdapter;
import com.yaomei.activity.info.R;

public class gridViewExt extends LinearLayout {
    public List<HashMap<String, Object>> tableRowsList;
    private List<HashMap<String, Object>> app = new ArrayList<HashMap<String, Object>>();
    private AppsAdapter adapter;

    onItemClickListener onItemClickEvent;
    onLongPressExt onLongPress;
    int checkRowID = -1; // 選中行的下標
    int checkColumnID = -1; // 選中列的下標
    int lastRowCount = -1; // 最後一行的總數
    private int ColumnCount; // 每列的總數

    public void setColumnCount(int count) {
        this.ColumnCount = count;
    }

    public int getColumnCount() {
        return ColumnCount;
    }

    public interface onItemClickListener {
        public boolean onItemClick(int position, MotionEvent event, View view);
    }

    public interface onLongPressExt {
        public boolean onLongPress(View view);
    }

    public gridViewExt(Context context) {
        this(context, null);
        // TODO Auto-generated constructor stub
    }

    public gridViewExt(Context context, AttributeSet attrs) {
        super(context, attrs);
        int resouceID = -1;
        TypedArray typedArray = context.obtainStyledAttributes(attrs,
                R.styleable.GridViewExt);
        int N = typedArray.getIndexCount();
        for (int i = 0; i < N; i++) {
            int attr = typedArray.getIndex(i);
            switch (attr) {
            case R.styleable.GridViewExt_ColumnCount:
                resouceID = typedArray.getInt(
                        R.styleable.GridViewExt_ColumnCount, 0);
                setColumnCount(resouceID);
                break;

            }
        }
        typedArray.recycle();
    }

    public void setOnItemClickListener(onItemClickListener click) {
        this.onItemClickEvent = click;
    }

    public void setOnLongPressListener(onLongPressExt longPress) {
        this.onLongPress = longPress;
    }

    public void NotifyDataChange() {
        removeAllViews();
    }

    void bindView() {
        removeAllViews();
        int count = adapter.getCount();
        TableCell[] cell = null;
        int j = 0;
        LinearLayout layout;
        tableRowsList = new ArrayList<HashMap<String, Object>>();
        for (int i = 0; i < count; i++) {
            j++;
            final int position = i;
            if (j > getColumnCount() || i == 0) {
                cell = new TableCell[getColumnCount()];
            }

            final View view = adapter.getView(i, null, null);

            view.setOnTouchListener(new OnTouchListener() {

                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    // TODO Auto-generated method stub
                    unCheckPressed();
                    checkRowID = -1;
                    checkColumnID = -1;
                    if (onItemClickEvent != null) {

                        onItemClickEvent.onItemClick(position, event, view);
                    }
                    return false;
                }
            });

            view.setOnLongClickListener(new OnLongClickListener() {

                @Override
                public boolean onLongClick(View v) {
                    if (onLongPress != null) {
                        onLongPress.onLongPress(v);
                    }
                    return true;
                }
            });
            cell[j - 1] = new TableCell(view);
            if (j == getColumnCount()) {
                lastRowCount = j;
                j = 0;
                HashMap<String, Object> map = new HashMap<String, Object>();
                TableRow tr = new TableRow(cell);
                map.put("tableRow", tr);
                tableRowsList.add(map);
                layout = new LinearLayout(getContext());
                addLayout(layout, cell, tr.getSize(), tr);

            } else if (i >= count - 1 && j > 0) {
                lastRowCount = j;
                HashMap<String, Object> map = new HashMap<String, Object>();
                TableRow tr = new TableRow(cell);
                map.put("tableRow", tr);
                tableRowsList.add(map);
                layout = new LinearLayout(getContext());
                addLayout(layout, cell, j, tr);
            }

        }

    }

    private void addLayout(LinearLayout layout, TableCell[] cell, int size,
            TableRow tr) {

        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(130,
                110);
        layout.setGravity(Gravity.LEFT);

        layout.setOrientation(LinearLayout.HORIZONTAL);
        for (int k = 0; k < size; k++) {
            View remoteView = (View) tr.getCellValue(k).getValue();
            layout.addView(remoteView, k, params);
        }
        LinearLayout.LayoutParams firstParams = new LinearLayout.LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        firstParams.leftMargin = 60;
        addView(layout, firstParams);
    }

    public void setAdapter(AppsAdapter appsAdapter) {
        this.adapter = appsAdapter;
        this.setOrientation(LinearLayout.VERTICAL);
        bindView();
    }

    public void checkPressed(int tableRowId, int tableRowColumnId) {
        ViewGroup view = (ViewGroup) this.getChildAt(tableRowId);

        checkColumnID = tableRowColumnId;
        checkRowID = tableRowId;
        changeImageState(view.getChildAt(tableRowColumnId), app);

    }

    public void onClick(int tableRowId, int tableRowColumnId, Context context) {
        LinearLayout view = (LinearLayout) ((ViewGroup) this
                .getChildAt(tableRowId)).getChildAt(tableRowColumnId);

        TextView tv = (TextView) view.findViewById(R.id.folder);
        final String[] name = tv.getText().toString().split("-");
        Intent intent = null;
        if (name[0].toString().equals("com.android.contacts")) {
            if (name[1].toString().equals(
                    "com.android.contacts.DialtactsActivity")) {
                intent = new Intent(Intent.ACTION_DIAL);
            }
            if (name[1].toString().equals(
                    "com.android.contacts.DialtactsContactsEntryActivity")) {
                intent = new Intent(Intent.ACTION_CALL_BUTTON);
            }
        } else {
            intent = getContext().getPackageManager()
                    .getLaunchIntentForPackage(name[0].toString());
        }
        context.startActivity(intent);

    }

    /**
     * 改變圖片狀態
     * 
     * @param v
     * @param list
     */
    private void changeImageState(View v, List<HashMap<String, Object>> list) {
        int size = list.size();
        for (int i = 0; i < size; i++) {
            View view = (View) list.get(i).get("touch");
            view.setPressed(false);
            list.remove(i);
        }
        v.setPressed(true);
        HashMap<String, Object> map = new HashMap<String, Object>();
        map.put("touch", v);
        list.add(map);

    }

    public void unCheckPressed() {
        if (checkColumnID != -1 && checkRowID != -1) {
            ViewGroup view = (ViewGroup) this.getChildAt(checkRowID);
            view.getChildAt(checkColumnID).setPressed(false);

        }
    }

    public class TableRow {
        private TableCell[] cell;

        public TableRow(TableCell[] cell) {
            this.cell = cell;
        }

        public int getSize() {
            return cell.length;
        }

        public TableCell getCellValue(int index) {
            if (index >= getSize()) {
                return null;
            }
            return cell[index];
        }

        public int getCellCount() {

            return cell.length;

        }

        public int getLastCellCount() {
            return lastRowCount;
        }
    }

    static public class TableCell {
        private Object value;

        public TableCell(Object value) {
            this.value = value;
        }

        public Object getValue() {
            return value;
        }
    }

}

 

 

 

每行顯示的LAYOUT文件:

 

<LinearLayout android:orientation="vertical"
    android:background="@drawable/lessbtn" android:gravity="center"
    android:layout_width="fill_parent" android:id="@+id/grid_layout"
    android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android">

    <ImageView android:id="@+id/btn_appicon"
        android:layout_width="55dip" android:layout_height="55dip"></ImageView>
    <TextView android:id="@+id/tv_name" android:layout_width="wrap_content"
        android:textColor="#030303" android:layout_height="wrap_content"></TextView>
    <TextView android:id="@+id/folder" android:layout_width="wrap_content"
        android:visibility="invisible" android:layout_height="wrap_content"></TextView>

</LinearLayout>

 

 

完成這一系列的編寫後,你就可以在xml直接寫或者在JAVA文件裡面new 出來,但注意要設置它每列顯示的個數。

下篇將講述如何實現手勢切屏,如何實現分頁顯示數據,如何實現封裝分頁控件。

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