編輯:關於Android編程
突然發現好久沒有寫博客了,一直放到筆記裡面,今天update一下。
最近做的一個項目中,是盒子+電視,用戶通過遙控器來操作。
這裡只是說下GridView在當前業務下的簡單使用,其實效果可以更多,實現的方式可以更高級。
比如下面這個開源項目:Android-tv-widget">https://github.com/FrozenFreeFall/Android-tv-widget
描述:一個界面裡面有多個Item選項,當進入到頁面後,默認選中第一個Item,並更新Item的背景為選中狀態,並且該GridView有OnItemSelectedListener和onItemClickListener以及OnLayoutChange監聽,使用OK按鈕,可以實現點擊效果。
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更新背景。
因為某些原因,圖片信息不能透露過多。就簡單截屏一兩個效果。
ViewPager是Android中比較常見的頁面切換控件, 同時, 在UIExplorerApp中也有ViewPagerAndroid的示例. 通過使用這個控件, 理解
問題:如果圖片很大,全部載入內存,而顯示屏又不大,那麼再大的圖片也不會提高視覺效果的,而且會消耗無謂的內存。 解決辦法就是根據實際需要多大的圖片,然後動態計算應該載入多大
微信的用戶數量日益增多,甚至有取代qq的趨勢,當我們跟一群人參加戶外活動的時候想加其他人的微信好友,您是不是要一個個的掃二維碼添加呢,那麼下面就
Android技術精髓-BackupActivity 首先介紹下今天主題BackupActivity功能:在Android應用UI activity 中繼承Asy