編輯:關於Android編程


樓主是在平板上測試的,圖片稍微有點大,大家看看效果就好
接下來貼源碼:
PinnedHeaderExpandableListView.java
要注意的是 在 onGroupClick方法中parent.setSelectedGroup(groupPosition)這句代碼的作用是點擊分組置頂,
我這邊不需要這個效果,QQ也沒有用到,所以給注釋了,大家如果需要可以解開注釋
package com.xiaos.view;
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnGroupClickListener;
public class PinnedHeaderExpandableListView extends ExpandableListView implements OnScrollListener,OnGroupClickListener {
public PinnedHeaderExpandableListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
registerListener();
}
public PinnedHeaderExpandableListView(Context context, AttributeSet attrs) {
super(context, attrs);
registerListener();
}
public PinnedHeaderExpandableListView(Context context) {
super(context);
registerListener();
}
/**
* Adapter 接口 . 列表必須實現此接口 .
*/
public interface HeaderAdapter {
public static final int PINNED_HEADER_GONE = 0;
public static final int PINNED_HEADER_VISIBLE = 1;
public static final int PINNED_HEADER_PUSHED_UP = 2;
/**
* 獲取 Header 的狀態
* @param groupPosition
* @param childPosition
* @return PINNED_HEADER_GONE,PINNED_HEADER_VISIBLE,PINNED_HEADER_PUSHED_UP 其中之一
*/
int getHeaderState(int groupPosition, int childPosition);
/**
* 配置 Header, 讓 Header 知道顯示的內容
* @param header
* @param groupPosition
* @param childPosition
* @param alpha
*/
void configureHeader(View header, int groupPosition,int childPosition, int alpha);
/**
* 設置組按下的狀態
* @param groupPosition
* @param status
*/
void setGroupClickStatus(int groupPosition, int status);
/**
* 獲取組按下的狀態
* @param groupPosition
* @return
*/
int getGroupClickStatus(int groupPosition);
}
private static final int MAX_ALPHA = 255;
private HeaderAdapter mAdapter;
/**
* 用於在列表頭顯示的 View,mHeaderViewVisible 為 true 才可見
*/
private View mHeaderView;
/**
* 列表頭是否可見
*/
private boolean mHeaderViewVisible;
private int mHeaderViewWidth;
private int mHeaderViewHeight;
public void setHeaderView(View view) {
mHeaderView = view;
AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
view.setLayoutParams(lp);
if (mHeaderView != null) {
setFadingEdgeLength(0);
}
requestLayout();
}
private void registerListener() {
setOnScrollListener(this);
setOnGroupClickListener(this);
}
/**
* 點擊 HeaderView 觸發的事件
*/
private void headerViewClick() {
long packedPosition = getExpandableListPosition(this.getFirstVisiblePosition());
int groupPosition = ExpandableListView.getPackedPositionGroup(packedPosition);
if (mAdapter.getGroupClickStatus(groupPosition) == 1) {
this.collapseGroup(groupPosition);
mAdapter.setGroupClickStatus(groupPosition, 0);
}
else{
this.expandGroup(groupPosition);
mAdapter.setGroupClickStatus(groupPosition, 1);
}
this.setSelectedGroup(groupPosition);
}
private float mDownX;
private float mDownY;
/**
* 如果 HeaderView 是可見的 , 此函數用於判斷是否點擊了 HeaderView, 並對做相應的處理 ,
* 因為 HeaderView 是畫上去的 , 所以設置事件監聽是無效的 , 只有自行控制 .
*/
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (mHeaderViewVisible) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
mDownX = ev.getX();
mDownY = ev.getY();
if (mDownX <= mHeaderViewWidth && mDownY <= mHeaderViewHeight) {
return true;
}
break;
case MotionEvent.ACTION_UP:
float x = ev.getX();
float y = ev.getY();
float offsetX = Math.abs(x - mDownX);
float offsetY = Math.abs(y - mDownY);
// 如果 HeaderView 是可見的 , 點擊在 HeaderView 內 , 那麼觸發 headerClick()
if (x <= mHeaderViewWidth && y <= mHeaderViewHeight
&& offsetX <= mHeaderViewWidth && offsetY <= mHeaderViewHeight) {
if (mHeaderView != null) {
headerViewClick();
}
return true;
}
break;
default:
break;
}
}
return super.onTouchEvent(ev);
}
@Override
public void setAdapter(ExpandableListAdapter adapter) {
super.setAdapter(adapter);
mAdapter = (HeaderAdapter) adapter;
}
/**
*
* 點擊了 Group 觸發的事件 , 要根據根據當前點擊 Group 的狀態來
*/
@Override
public boolean onGroupClick(ExpandableListView parent,View v,int groupPosition,long id) {
if (mAdapter.getGroupClickStatus(groupPosition) == 0) {
mAdapter.setGroupClickStatus(groupPosition, 1);
parent.expandGroup(groupPosition);
//Header自動置頂
//parent.setSelectedGroup(groupPosition);
} else if (mAdapter.getGroupClickStatus(groupPosition) == 1) {
mAdapter.setGroupClickStatus(groupPosition, 0);
parent.collapseGroup(groupPosition);
}
// 返回 true 才可以彈回第一行 , 不知道為什麼
return true;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (mHeaderView != null) {
measureChild(mHeaderView, widthMeasureSpec, heightMeasureSpec);
mHeaderViewWidth = mHeaderView.getMeasuredWidth();
mHeaderViewHeight = mHeaderView.getMeasuredHeight();
}
}
private int mOldState = -1;
@Override
protected void onLayout(boolean changed, int left, int top, int right,int bottom) {
super.onLayout(changed, left, top, right, bottom);
final long flatPostion = getExpandableListPosition(getFirstVisiblePosition());
final int groupPos = ExpandableListView.getPackedPositionGroup(flatPostion);
final int childPos = ExpandableListView.getPackedPositionChild(flatPostion);
int state = mAdapter.getHeaderState(groupPos, childPos);
if (mHeaderView != null && mAdapter != null && state != mOldState) {
mOldState = state;
mHeaderView.layout(0, 0, mHeaderViewWidth, mHeaderViewHeight);
}
configureHeaderView(groupPos, childPos);
}
public void configureHeaderView(int groupPosition, int childPosition) {
if (mHeaderView == null || mAdapter == null
|| ((ExpandableListAdapter) mAdapter).getGroupCount() == 0) {
return;
}
int state = mAdapter.getHeaderState(groupPosition, childPosition);
switch (state) {
case HeaderAdapter.PINNED_HEADER_GONE: {
mHeaderViewVisible = false;
break;
}
case HeaderAdapter.PINNED_HEADER_VISIBLE: {
mAdapter.configureHeader(mHeaderView, groupPosition,childPosition, MAX_ALPHA);
if (mHeaderView.getTop() != 0){
mHeaderView.layout(0, 0, mHeaderViewWidth, mHeaderViewHeight);
}
mHeaderViewVisible = true;
break;
}
case HeaderAdapter.PINNED_HEADER_PUSHED_UP: {
View firstView = getChildAt(0);
int bottom = firstView.getBottom();
// intitemHeight = firstView.getHeight();
int headerHeight = mHeaderView.getHeight();
int y;
int alpha;
if (bottom < headerHeight) {
y = (bottom - headerHeight);
alpha = MAX_ALPHA * (headerHeight + y) / headerHeight;
} else {
y = 0;
alpha = MAX_ALPHA;
}
mAdapter.configureHeader(mHeaderView, groupPosition,childPosition, alpha);
if (mHeaderView.getTop() != y) {
mHeaderView.layout(0, y, mHeaderViewWidth, mHeaderViewHeight + y);
}
mHeaderViewVisible = true;
break;
}
}
}
@Override
/**
* 列表界面更新時調用該方法(如滾動時)
*/
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
if (mHeaderViewVisible) {
//分組欄是直接繪制到界面中,而不是加入到ViewGroup中
drawChild(canvas, mHeaderView, getDrawingTime());
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {
final long flatPos = getExpandableListPosition(firstVisibleItem);
int groupPosition = ExpandableListView.getPackedPositionGroup(flatPos);
int childPosition = ExpandableListView.getPackedPositionChild(flatPos);
configureHeaderView(groupPosition, childPosition);
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
}
PinnedHeaderExpandableAdapter.java 適配器
實現了PinnedHeaderExpandableListView中HeaderAdapter接口
package com.xiaos.adapter;
import android.content.Context;
import android.util.SparseIntArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.xiaos.pinnedheaderexpandable.R;
import com.xiaos.view.PinnedHeaderExpandableListView;
import com.xiaos.view.PinnedHeaderExpandableListView.HeaderAdapter;
public class PinnedHeaderExpandableAdapter extends BaseExpandableListAdapter implements HeaderAdapter{
private String[][] childrenData;
private String[] groupData;
private Context context;
private PinnedHeaderExpandableListView listView;
private LayoutInflater inflater;
public PinnedHeaderExpandableAdapter(String[][] childrenData,String[] groupData
,Context context,PinnedHeaderExpandableListView listView){
this.groupData = groupData;
this.childrenData = childrenData;
this.context = context;
this.listView = listView;
inflater = LayoutInflater.from(this.context);
}
@Override
public Object getChild(int groupPosition, int childPosition) {
return childrenData[groupPosition][childPosition];
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return 0;
}
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
View view = null;
if (convertView != null) {
view = convertView;
} else {
view = createChildrenView();
}
TextView text = (TextView)view.findViewById(R.id.childto);
text.setText(childrenData[groupPosition][childPosition]);
return view;
}
@Override
public int getChildrenCount(int groupPosition) {
return childrenData[groupPosition].length;
}
@Override
public Object getGroup(int groupPosition) {
return groupData[groupPosition];
}
@Override
public int getGroupCount() {
return groupData.length;
}
@Override
public long getGroupId(int groupPosition) {
return 0;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
View view = null;
if (convertView != null) {
view = convertView;
} else {
view = createGroupView();
}
ImageView iv = (ImageView)view.findViewById(R.id.groupIcon);
if (isExpanded) {
iv.setImageResource(R.drawable.btn_browser2);
}
else{
iv.setImageResource(R.drawable.btn_browser);
}
TextView text = (TextView)view.findViewById(R.id.groupto);
text.setText(groupData[groupPosition]);
return view;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
private View createChildrenView() {
return inflater.inflate(R.layout.child, null);
}
private View createGroupView() {
return inflater.inflate(R.layout.group, null);
}
@Override
public int getHeaderState(int groupPosition, int childPosition) {
final int childCount = getChildrenCount(groupPosition);
if (childPosition == childCount - 1) {
return PINNED_HEADER_PUSHED_UP;
} else if (childPosition == -1
&& !listView.isGroupExpanded(groupPosition)) {
return PINNED_HEADER_GONE;
} else {
return PINNED_HEADER_VISIBLE;
}
}
@Override
public void configureHeader(View header, int groupPosition,
int childPosition, int alpha) {
String groupData = this.groupData[groupPosition];
((TextView) header.findViewById(R.id.groupto)).setText(groupData);
}
private SparseIntArray groupStatusMap = new SparseIntArray();
@Override
public void setGroupClickStatus(int groupPosition, int status) {
groupStatusMap.put(groupPosition, status);
}
@Override
public int getGroupClickStatus(int groupPosition) {
if (groupStatusMap.keyAt(groupPosition)>=0) {
return groupStatusMap.get(groupPosition);
} else {
return 0;
}
}
}
MainActivity.java主Activity
package com.xiaos.pinnedheaderexpandable;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnGroupClickListener;
import com.xiaos.adapter.PinnedHeaderExpandableAdapter;
import com.xiaos.view.PinnedHeaderExpandableListView;
public class MainActivity extends Activity{
private PinnedHeaderExpandableListView explistview;
private String[][] childrenData = new String[10][10];
private String[] groupData = new String[10];
private int expandFlag = -1;//控制列表的展開
private PinnedHeaderExpandableAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_main);
initView();
initData();
}
/**
* 初始化VIEW
*/
private void initView() {
explistview = (PinnedHeaderExpandableListView)findViewById(R.id.explistview);
}
/**
* 初始化數據
*/
private void initData() {
for(int i=0;i<10;i++){
groupData[i] = 分組+i;
}
for(int i=0;i<10;i++){
for(int j=0;j<10;j++){
childrenData[i][j] = 好友+i+-+j;
}
}
//設置懸浮頭部VIEW
explistview.setHeaderView(getLayoutInflater().inflate(R.layout.group_head,
explistview, false));
adapter = new PinnedHeaderExpandableAdapter(childrenData, groupData, getApplicationContext(),explistview);
explistview.setAdapter(adapter);
//設置單個分組展開
//explistview.setOnGroupClickListener(new GroupClickListener());
}
class GroupClickListener implements OnGroupClickListener{
@Override
public boolean onGroupClick(ExpandableListView parent, View v,
int groupPosition, long id) {
if (expandFlag == -1) {
// 展開被選的group
explistview.expandGroup(groupPosition);
// 設置被選中的group置於頂端
explistview.setSelectedGroup(groupPosition);
expandFlag = groupPosition;
} else if (expandFlag == groupPosition) {
explistview.collapseGroup(expandFlag);
expandFlag = -1;
} else {
explistview.collapseGroup(expandFlag);
// 展開被選的group
explistview.expandGroup(groupPosition);
// 設置被選中的group置於頂端
explistview.setSelectedGroup(groupPosition);
expandFlag = groupPosition;
}
return true;
}
}
}
child.xml

Android獲得當前系統時間、星期幾、周幾
Android獲得當前系統時間有好幾種方法,本文使用的是System.currentTimeMillis->Date+SimpleDateFormat,我覺得這種方
android---widgets的使用
一.效果展示在Android手機的桌面上,我們經常可以看到如下小控件在這些控件上,可以顯示我們APP的一些重要的交互信息,以我最近開發的手機衛士為例,在widget上可以
qq厘米秀表情怎麼設置聲音
大家現在聊天文字已經不足以表達內心情緒了,所以有了表情包,而且現在的QQ裡面出來了厘米秀,表情就更多了,不僅有動態gif,還有聲音呢,自帶bgm,下面小編就
Android學習之獲取系統應用信息列表的實現
前言:好幾天電腦打不開CSDN博客,也不知道怎麼回事,今天下班回來突然能打開了,遂將周末實現的一個效果貼上。實現功能:獲取手機應用圖標,名稱,時間(安裝時間/更新時間),