Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 自定義GridView的使用(盒子應用)

自定義GridView的使用(盒子應用)

編輯:關於Android編程

突然發現好久沒有寫博客了,一直放到筆記裡面,今天update一下。


最近做的一個項目中,是盒子+電視,用戶通過遙控器來操作。
這裡只是說下GridView在當前業務下的簡單使用,其實效果可以更多,實現的方式可以更高級。
比如下面這個開源項目:Android-tv-widget">https://github.com/FrozenFreeFall/Android-tv-widget

描述:一個界面裡面有多個Item選項,當進入到頁面後,默認選中第一個Item,並更新Item的背景為選中狀態,並且該GridView有OnItemSelectedListener和onItemClickListener以及OnLayoutChange監聽,使用OK按鈕,可以實現點擊效果。

自定義控件MyGridView.java

package com.shenqijiazu.daillylesson.widget;

import com.shenqijiazu.daillylesson.R;

import android.content.Context;
import android.content.res.TypedArray;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.view.View.OnLayoutChangeListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.GridView;

/**
 * @author xxiang1x
 * 
 *         教師界面、班級界面、等都用到GridView,這個把公共部分提取出來。比如選中效果,制作成自定義控件。
 */
public class MyGridView extends GridView implements OnLayoutChangeListener,
        android.widget.AdapterView.OnItemSelectedListener,
        android.widget.AdapterView.OnItemClickListener {

    /**
     * 被選中的GridView's adapter's item.xml中,對應布局layout。用於設置背景
     */
    private int selectedLayoutResId = -1;
    /**
     * 未被選中時候的背景
     */
    private int unSelectedResBgId = -1;
    /**
     * 被選中時候的背景
     */
    private int selectedResBgId = -1;
    /**
     * 布局layout的名字。因為這個布局是Adapter裡面item的布局id,所以我們這裡用name來綁定到對應的id layout
     */
    private String selectedItemLayoutName;

    public MyGridView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
        initMonitors();
    }

    /**
     * 設置監聽
     */
    private void initMonitors() {
        // TODO Auto-generated method stub
        this.setOnItemSelectedListener(this);
        this.addOnLayoutChangeListener(this);
        this.setOnItemClickListener(this);
        this.setFocusable(true);
        this.setFocusableInTouchMode(true);
    }

    public MyGridView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initMonitors();
        // TODO Auto-generated constructor stub

        initAttributes(context, attrs, defStyle);
    }

    /**
     * Get自定義屬性。
     * 
     * @param context
     * @param attrs
     * @param defStyle
     */
    private void initAttributes(Context context, AttributeSet attrs,
            int defStyle) {
        // TODO Auto-generated method stub
        TypedArray a = null;
        try {

            // a = context.obtainStyledAttributes(attrs,
            // R.styleable.MagicGridView, defStyle, 0);
            a = context
                    .obtainStyledAttributes(attrs, R.styleable.MagicGridView);

            selectedResBgId = a.getResourceId(
                    R.styleable.MagicGridView_selected_item_background, -1);
            unSelectedResBgId = a.getResourceId(
                    R.styleable.MagicGridView_unselected_item_background, -1);

            selectedItemLayoutName = a
                    .getString(R.styleable.MagicGridView_selected_item_layout_name);
            if (!TextUtils.isEmpty(selectedItemLayoutName)) {
                // 聽過設定layout的名字去獲取對應的id
                selectedLayoutResId = a.getResources().getIdentifier(
                        selectedItemLayoutName, "id", context.getPackageName());
            }
        } finally {

            a.recycle();
        }
    }

    public MyGridView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initMonitors();
        // TODO Auto-generated constructor stub
        initAttributes(context, attrs, -1);
    }

    @Override
    public void onLayoutChange(View v, int left, int top, int right,
            int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
        // TODO Auto-generated method stub

        this.setSelection(0);

    }

    /**
     * 記錄之前的被選中的View
     */
    private int mPrevPosition = -1;

    @Override
    public void onItemSelected(AdapterView parent, View view, int position,
            long id) {
        // TODO Auto-generated method stub

        responseSelectAndClick(parent, view, position, id);

    }

    @Override
    public void onNothingSelected(AdapterView parent) {
        // TODO Auto-generated method stub

    }

    /**
     * 響應選擇和點擊效果。
     * 
     * @param parent
     * @param view
     * @param position
     * @param id
     */
    private void responseSelectAndClick(AdapterView parent, View view,
            int position, long id) {
        // TODO Auto-generated method stub
        if (null != view) {
            if (selectedLayoutResId == -1 || selectedResBgId == -1
                    || unSelectedResBgId == -1) {

                return;
            }
            if (mPrevPosition != -1 && mPrevPosition != position) {
                // 首先恢復狀態
                ViewGroup mPrevViewGroup = (ViewGroup) parent
                        .getChildAt(mPrevPosition);
                if (null != mPrevViewGroup) {

                    ((ViewGroup) mPrevViewGroup).findViewById(
                            selectedLayoutResId).setBackgroundResource(
                            unSelectedResBgId);
                }
            }
            if (mPrevPosition != position) {
                // 把選中狀態設置到新的View
                mPrevPosition = position;
                ((ViewGroup) view).findViewById(selectedLayoutResId)
                        .setBackgroundResource(selectedResBgId);
            }
        }
    }

    /**
     * 

* 如果動態創建的GridView則使用這個方式設置對應值。 *

*

* 如果是xml中配置則使用自定義屬性添加到xml中。 *

* * @param layoutResId * @param bgSelectedResId * @param unSelectedResId */ public void setSelectedEffectRes(int layoutResId, int bgSelectedResId, int unSelectedResId) { this.selectedLayoutResId = layoutResId; this.selectedResBgId = bgSelectedResId; this.unSelectedResBgId = unSelectedResId; } @Override public void onItemClick(AdapterViewparent, View view, int position, long id) { // TODO Auto-generated method stub onItemClickCallBack.onItemClick(parent, view, position, id); // 點擊也加上效果。 responseSelectAndClick(parent, view, position, id); } private OnItemClickCallBack onItemClickCallBack; public void setOnItemClickCallBack(OnItemClickCallBack onItemClickCallBack) { this.onItemClickCallBack = onItemClickCallBack; } public interface OnItemClickCallBack { void onItemClick(AdapterViewparent, View view, int position, long id); } }

自定義相關屬性:

    
    
        
        
        
    
selected_item_layout_name對應的是該界面的GridView所使用的Adapter的Item布局中外層Layout的resource id。 selected_item_background對應Item為選中狀態時候的背景 unselected_item_background對應Item為非選中狀態時候的背景

在xml中的定義:


            

其中的重點在於下面屬性的定義:

app:selected_item_background="@drawable/dialog_classinfo_item_pressed"
                app:selected_item_layout_name="dialog_classes_bglayout"
                app:unselected_item_background="@drawable/dialog_classinfo_item_normal"

對應的MyGridView.java中的解析:

private void initAttributes(Context context, AttributeSet attrs,
            int defStyle) {
        // TODO Auto-generated method stub
        TypedArray a = null;
        try {

            // a = context.obtainStyledAttributes(attrs,
            // R.styleable.MagicGridView, defStyle, 0);
            a = context
                    .obtainStyledAttributes(attrs, R.styleable.MagicGridView);

            selectedResBgId = a.getResourceId(
                    R.styleable.MagicGridView_selected_item_background, -1);
            unSelectedResBgId = a.getResourceId(
                    R.styleable.MagicGridView_unselected_item_background, -1);

            selectedItemLayoutName = a
                    .getString(R.styleable.MagicGridView_selected_item_layout_name);
            if (!TextUtils.isEmpty(selectedItemLayoutName)) {
                // 聽過設定layout的名字去獲取對應的id
                selectedLayoutResId = a.getResources().getIdentifier(
                        selectedItemLayoutName, "id", context.getPackageName());
            }
        } finally {

            a.recycle();
        }
    }

因為xml中無法指定別的xml文件裡面對應id的layout,所以這裡使用a.getResources().getIdentifier方法,利用layout的name獲取到對應的layout resource id ,此時就綁定了Adapter Item布局中對應id的ViewGroup,這樣就可以進行其他的操作了。

selectedItemLayoutName = a
                    .getString(R.styleable.MagicGridView_selected_item_layout_name);
            if (!TextUtils.isEmpty(selectedItemLayoutName)) {
                // 聽過設定layout的名字去獲取對應的id
                selectedLayoutResId = a.getResources().getIdentifier(
                        selectedItemLayoutName, "id", context.getPackageName());
            }

最後說一下mPrevPosition這個變量,主要在responseSelectAndClick()方法中使用。當使用遙控左右上下切換的時候,我們需要將前一個的背景還原,新的選中item更新背景。
這裡寫圖片描述

因為某些原因,圖片信息不能透露過多。就簡單截屏一兩個效果。

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