自定义expendableListView实现与QQ联系人一样效果的通讯录
2016-07-23 09:07
337 查看
最近在项目中需要实现QQ联系人一样效果的通讯录,并且实现点击刷新CheckBox,在网上查看了很多安,发现并没有什么系统或有效的方法,能够应用到当前的实际开发中来,而且有很多人出现了因为item重用出现的选择一个item出现多个item的checkBox都被选择的情况,出现这种情况的原因在这里我就不多说了,因为只要了解过listview的adapter的人都知道。下面直接上代码:
下面是adapter的代码:
activty代码:
这是从自己项目中剥离出来的code,涉及公司保密协议,故不给详细dome,主要业务以及思路已经实现,希望大家多给出指导性意见! 谢谢。
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 ContactsExpandableListView extends ExpandableListView implements OnScrollListener, OnGroupClickListener { public ContactsExpandableListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); registerListener(); } public ContactsExpandableListView(Context context, AttributeSet attrs) { super(context, attrs); registerListener(); } public ContactsExpandableListView(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); if (view != null) { 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); if (mAdapter != null) {// 不加空指针异常 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) { } }
下面是adapter的代码:
import java.util.List; import java.util.Map; import android.annotation.SuppressLint; 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.CheckBox; import android.widget.ImageView; import android.widget.TextView; import com.example.yihua_sdwms_mobile_app.R; import com.yihuacomputer.sdwms.init.fragement.bean.MailEntity; import com.yihuacomputer.sdwms.init.view.PinnedHeaderExpandableListView; import com.yihuacomputer.sdwms.init.view.PinnedHeaderExpandableListView.HeaderAdapter; public class ContactsExpandableAdapter extends BaseExpandableListAdapter implements HeaderAdapter { public static final int START_JUMP_PAGE = 1;// 跳转tag public static final int RETURN_JUMP_PAGE = 2;// 返回tag public static final String START_JUMP_FLAG = "3";// 返回tag private List<List<Object>> childrenData; private List<String> groupData;// String [] 改成List<String> 徐振浩 2016年6月23日 private Context context; private PinnedHeaderExpandableListView listView; private LayoutInflater inflater; /** 测试ChildItem是否选中 **/ private List<List<Map<String, Boolean>>> isChecked; public ContactsExpandableAdapter(List<List<Object>> childrenData, List<String> groupData, Context context, PinnedHeaderExpandableListView listView, List<List<Map<String, Boolean>>> isChecked) { this.groupData = groupData; this.childrenData = childrenData; this.context = context; this.listView = listView; this.isChecked = isChecked; inflater = LayoutInflater.from(this.context); } @Override public Object getChild(int groupPosition, int childPosition) { return childrenData.get(groupPosition).get(childPosition); } @Override public long getChildId(int groupPosition, int childPosition) { return 0; } @Override public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { ChildViewHolder holder = null; if (convertView == null) { holder = new ChildViewHolder(); convertView = createChildrenView(); holder.title = (TextView) convertView .findViewById(R.id.child_title); holder.content = (TextView) convertView .findViewById(R.id.child_content); holder.cb = (CheckBox) convertView.findViewById(R.id.is_check); convertView.setTag(holder); } else { holder = (ChildViewHolder) convertView.getTag(); } MailEntity mailEntity = null; if (childrenData != null && childrenData.size() > 0) { mailEntity = (MailEntity) childrenData.get(groupPosition).get( childPosition); holder.title.setText(mailEntity.getName()); holder.content.setText(mailEntity.getWorkPosition()); /** 测试CheckBox选中状态 **/ holder.cb.setChecked(isChecked.get(groupPosition).get(childPosition).get("CB_CHECK")); } return convertView; } public class ChildViewHolder { public TextView title; public TextView content; public CheckBox cb; } @Override public int getChildrenCount(int groupPosition) { return childrenData.get(groupPosition).size(); } @Override public Object getGroup(int groupPosition) { return groupData.get(groupPosition); } @Override public int getGroupCount() { return groupData.size(); } @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(); } TextView text = (TextView) view.findViewById(R.id.groupto); text.setText(groupData.get(groupPosition)); TextView textNum = (TextView) view.findViewById(R.id.group_statistics); textNum.setText(new StringBuffer().append("[") .append(childrenData.get(groupPosition).size()).append("]") .toString()); ImageView iv = (ImageView) view.findViewById(R.id.group_contacts_iv); if (isExpanded) { iv.setImageResource(R.drawable.icon_arrow_open); } else { iv.setImageResource(R.drawable.icon_arrow_close); } return view; } @Override public boolean hasStableIds() { return true; } @Override public boolean isChildSelectable(int groupPosition, int childPosition) { return true; } @SuppressLint("InflateParams") private View createChildrenView() { return inflater.inflate(R.layout.child_contacts, null); } @SuppressLint("InflateParams") private View createGroupView() { return inflater.inflate(R.layout.group_contacts, 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.get(groupPosition); // 周title ((TextView) header.findViewById(R.id.groupto)).setText(groupData); // child Item数量 ((TextView) header.findViewById(R.id.group_statistics)) .setText(new StringBuffer().append("[") .append(childrenData.get(groupPosition).size()) .append("]").toString()); } 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; } } }
activty代码:
import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import com.example.yihua_sdwms_mobile_app.R; import com.yihuacomputer.sdwms.db.ContactsDao; import com.yihuacomputer.sdwms.db.MyPreference; import com.yihuacomputer.sdwms.init.MainActivity; import com.yihuacomputer.sdwms.init.fragement.bean.MailEntity; import com.yihuacomputer.sdwms.init.view.PinnedHeaderExpandableListView; import com.yihuacomputer.sdwms.management.contasts.ContactsExpandableAdapter; import com.yihuacomputer.sdwms.management.contasts.ContactsExpandableAdapter.ChildViewHolder; import com.yihuacomputer.sdwms.utils.MyUtil; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.ExpandableListView; import android.widget.ImageView; import android.widget.ExpandableListView.OnChildClickListener; import android.widget.TextView; /** * * @ClassName: NewContactsActivity * @Description: TODO(新通讯录,使用ExpandableListView实现) * @author XuZhenHao * @date 2016-7-3 上午11:26:48 */ public class NewContactsActivity extends Activity implements OnClickListener { /** 取消当前操作返回上一个页面 **/ private ImageView backBtn; /** 完成选择返回上一个页面 **/ private TextView completeBtn; /** 展示当前被选则的对象 **/ private TextView showSelectedTv; /** 联系人二级列表 **/ private PinnedHeaderExpandableListView contactsLv; /** 联系人二级列表适配器 **/ private ContactsExpandableAdapter adapter; /** sQlite数据库Dao **/ private ContactsDao dao = null; /** 二级列表父item **/ private List<String> groupData = null; /** 二级列表子item **/ private List<List<Object>> childrenData = null; /** 周报联系人实体 **/ private ArrayList<MailEntity> mailInfoList = null; /****/ private ArrayList<String> typeList = null; private MyPreference pre = null; /** **/ private String personName = ""; /** 被选中者名称 **/ private String selecterName = ""; /** 被选中者Id **/ private String selecterId = ""; /** 显示 **/ private static final String TYPE_SHOW = "show"; /** 发送 **/ private static final String TYPE_SEND = "send"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_new_contacts); pre = new MyPreference(NewContactsActivity.this); Intent intent = getIntent(); personName = intent.getStringExtra("personName") == null ? "" : intent .getStringExtra("personName"); initView(); } /** * * @Title: initView * @Description: TODO(初始化控件) * @param 设定文件 * @return void 返回类型 * */ private void initView() { backBtn = (ImageView) findViewById(R.id.title_left_image); backBtn.setOnClickListener(this); completeBtn = (TextView) findViewById(R.id.sendBtn); completeBtn.setOnClickListener(this); showSelectedTv = (TextView) findViewById(R.id.show_selected_tv); showSelectedTv.setText(personName); contactsLv = (PinnedHeaderExpandableListView) findViewById(R.id.contacts_lv); dao = new ContactsDao(this); groupData = new ArrayList<String>(); childrenData = new ArrayList<List<Object>>(); mailInfoList = dao.selectAll(); typeList = dao.distinctAll(); Log.i("typeList", typeList.size() + ""); if (mailInfoList.size() > 0) { /* 如果集合大小大于 */ integrateData(); initData(); isSpread(adapter.getGroupCount(), mailInfoList.size()); } } @Override public void onClick(View v) { switch (v.getId()) { case R.id.title_left_image: finish(); break; case R.id.sendBtn: getSelecter(TYPE_SEND); Intent returnIntent = new Intent(); returnIntent.putExtra(SELECTER_NAME, selecterName); returnIntent.putExtra(SELECTER_ID, selecterId); setResult(10086, returnIntent); finish(); break; default: break; } } /** * * @Title: getSelecter * @Description: TODO(将被选中者的姓名和id拼接成一个字符串) * @param 设定文件 * @return void 返回类型 * */ private void getSelecter(String type) { /** 用于拼接被选则者姓名 **/ String showSelecter = ""; for (int i = 0; i < selecterList.size(); i++) { for (int j = 0; j < selecterList.get(i).size(); j++) { String mSelecterName = selecterList.get(i).get(j) .get(SELECTER_NAME); String mSelecterId = selecterList.get(i).get(j) .get(SELECTER_ID); if (mSelecterName != null && mSelecterId != null && type.equals(TYPE_SEND)) { selecterName = selecterName + mSelecterName + ","; selecterId = selecterId + mSelecterId + ","; } else if (mSelecterName != null && mSelecterId != null && type.equals(TYPE_SHOW)) { showSelecter = showSelecter + mSelecterName + ","; } else { } } } /* 将拼接好的字符串显示 */ showSelectedTv.setText(showSelecter); } /** * * @Title: initData * @Description: TODO(初始化数据) * @param 设定文件 * @return void 返回类型 */ private void initData() { // 设置悬浮头部VIEW contactsLv.setHeaderView(NewContactsActivity.this.getLayoutInflater() .inflate(R.layout.group_head_contacts, contactsLv, false)); adapter = new ContactsExpandableAdapter(childrenData, groupData, NewContactsActivity.this, contactsLv, selectedList); contactsLv.setAdapter(adapter); MyUtil.closeSoftKeyBoard(MainActivity.getMainContext()); contactsLv.setOnChildClickListener(new OnChildClickListener() { @Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { /******************* 测试CheckBox选中状态 ********************/ ChildViewHolder holder = (ChildViewHolder) v.getTag(); holder.cb.toggle(); MailEntity mailEntity = (MailEntity) childrenData.get( groupPosition).get(childPosition); if (selectedList.get(groupPosition).get(childPosition) .get("CB_CHECK")) { /* * 如果当前item的CheckBox的选择状态为true,则将其状态集合对应的position修改为false, * 并在被选择对象容器将对象覆盖为Null */ selectedList.get(groupPosition).get(childPosition) .put("CB_CHECK", false); selecterList.get(groupPosition).get(childPosition) .put(SELECTER_NAME, null); selecterList.get(groupPosition).get(childPosition) .put(SELECTER_ID, null); } else { /* * 如果当前item的CheckBox选择状态为false,则将其状态集合对应的position修改为false, * 并将对象中put到容器中 */ selectedList.get(groupPosition).get(childPosition) .put("CB_CHECK", true); selecterList.get(groupPosition).get(childPosition) .put(SELECTER_NAME, mailEntity.getName()); selecterList.get(groupPosition).get(childPosition) .put(SELECTER_ID, mailEntity.getId()); } getSelecter(TYPE_SHOW); adapter.notifyDataSetChanged(); return true; } }); } private List<Object> grandsonData = null; private void integrateData() { groupData.clear(); childrenData.clear(); List<String> containList = new ArrayList<>(); if (mailInfoList.size() > 0) { /* 大销售(所有)>商务经理(所有)>各部门负责人>其他 */ containList.add("大销售"); containList.add("商务经理"); containList.add("部门负责人"); containList.add("其他"); } for (int i = 0; i < containList.size(); i++) { grandsonData = new ArrayList<Object>(); for (int j = 0; j < mailInfoList.size(); j++) { MailEntity entity = mailInfoList.get(j); if (entity.getPostType().equals(containList.get(i)) && !entity.getName().equals(pre.getUserName())) { grandsonData.add(mailInfoList.get(j)); } } if (grandsonData.size() > 0) { groupData.add(containList.get(i)); childrenData.add(grandsonData); } } initCheckBoxState(personName); } /** ChildItem CheckBox 选中状态集合 **/ private List<List<Map<String, Boolean>>> selectedList; /** 被选中者集合 **/ private List<List<Map<String, String>>> selecterList; /** CheckBox选中 **/ private static final String CB_CHECK = "CB_CHECK"; /** 被选中者姓名 **/ private static final String SELECTER_NAME = "SELECTERNAME"; /** 被选中者id **/ private static final String SELECTER_ID = "SELECTERID"; /** * * @Title: initCheckBoxState * @Description: TODO(初始化二级列表ChildItem选中状态,以及选中者容器) * @param 设定文件 * @return void 返回类型 * */ public void initCheckBoxState(String selected) { selectedList = new ArrayList<List<Map<String, Boolean>>>(); selecterList = new ArrayList<List<Map<String, String>>>(); for (int i = 0; i < childrenData.size(); i++) { /** 选中状态子集合 **/ List<Map<String, Boolean>> mSelectedList = new ArrayList<Map<String, Boolean>>(); /** 被选中者子容器 **/ List<Map<String, String>> mSelecterList = new ArrayList<Map<String, String>>(); for (int j = 0; j < childrenData.get(i).size(); j++) { /** 邮件实体 **/ MailEntity mailEntity = (MailEntity) childrenData.get(i).get(j); /** 被选中状态Map **/ Map<String, Boolean> childCb = new HashMap<String, Boolean>(); /** 被选中者容器Map **/ Map<String, String> childSelectMap = new HashMap<String, String>(); if (selected.contains(mailEntity.getName())) { childCb.put(CB_CHECK, true); childSelectMap.put(SELECTER_NAME, mailEntity.getName()); childSelectMap.put(SELECTER_ID, mailEntity.getId()); } else { childCb.put(CB_CHECK, false); childSelectMap.put(SELECTER_NAME, null); childSelectMap.put(SELECTER_ID, null); } mSelectedList.add(childCb); mSelecterList.add(childSelectMap); } selectedList.add(mSelectedList); selecterList.add(mSelecterList); } } /** * * @Title: isSpread * @Description: TODO(用于判定二级列表是否展开,目前只用于初始化加载数据徐振浩2016年7月3日) * @param @param groupCount 设定文件 * @return void 返回类型 * @author 徐振浩 * @date 2016年6月23日 * */ private void isSpread(int groupCount, int dataCount) { // 当总数据小于100的时候才默认展开 if (dataCount < 100) { for (int i = 0; i < groupCount; i++) { contactsLv.expandGroup(i); adapter.setGroupClickStatus(i, 1); } } } }
这是从自己项目中剥离出来的code,涉及公司保密协议,故不给详细dome,主要业务以及思路已经实现,希望大家多给出指导性意见! 谢谢。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories