最近在项目中需要实现QQ联系人一样效果的通讯录,并且实现点击刷新CheckBox,在网上查看了很多安,发现并没有什么系统或有效的方法,能够应用到当前的实际开发中来,而且有很多人出现了因为item重用出现的选择一个item出现多个item的checkBox都被选择的情况,出现这种情况的原因在这里我就不多说了,因为只要了解过listview的adapter的人都知道。下面直接上代码:

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 ExpandableListViewimplements 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* 是画上去的 , 所以设置事件监听是无效的 , 只有自行控制 .*/@Overridepublic 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);}@Overridepublic void setAdapter(ExpandableListAdapter adapter) {super.setAdapter(adapter);mAdapter = (HeaderAdapter) adapter;}/**** 点击了 Group 触发的事件 , 要根据根据当前点击 Group 的状态来*/@Overridepublic 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;}@Overrideprotected 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;@Overrideprotected 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;}}}/*** 列表界面更新时调用该方法(如滚动时)*/@Overrideprotected void dispatchDraw(Canvas canvas) {super.dispatchDraw(canvas);if (mHeaderViewVisible) {// 分组栏是直接绘制到界面中,而不是加入到ViewGroup中drawChild(canvas, mHeaderView, getDrawingTime());}}@Overridepublic 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);}@Overridepublic 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 BaseExpandableListAdapterimplements HeaderAdapter {public static final int START_JUMP_PAGE = 1;// 跳转tagpublic static final int RETURN_JUMP_PAGE = 2;// 返回tagpublic static final String START_JUMP_FLAG = "3";// 返回tagprivate 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);}@Overridepublic Object getChild(int groupPosition, int childPosition) {return childrenData.get(groupPosition).get(childPosition);}@Overridepublic long getChildId(int groupPosition, int childPosition) {return 0;}@Overridepublic 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;}@Overridepublic int getChildrenCount(int groupPosition) {return childrenData.get(groupPosition).size();}@Overridepublic Object getGroup(int groupPosition) {return groupData.get(groupPosition);}@Overridepublic int getGroupCount() {return groupData.size();}@Overridepublic long getGroupId(int groupPosition) {return 0;}@Overridepublic 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;}@Overridepublic boolean hasStableIds() {return true;}@Overridepublic 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);}@Overridepublic 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;}}@Overridepublic 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();@Overridepublic void setGroupClickStatus(int groupPosition, int status) {groupStatusMap.put(groupPosition, status);}@Overridepublic 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";@Overrideprotected 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());}}@Overridepublic 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() {// 设置悬浮头部VIEWcontactsLv.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() {@Overridepublic 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,主要业务以及思路已经实现,希望大家多给出指导性意见! 谢谢。

自定义expendableListView实现与QQ联系人一样效果的通讯录相关推荐

  1. 自定义 Behavior,实现 QQ 联系人 tab 和 header 动画

    CustomBehavior 项目地址:XiqingLiu/CustomBehavior  简介:自定义 Behavior,实现 QQ 联系人 tab 和 header 动画 更多:作者   提 Bu ...

  2. Android自定义View之仿QQ运动步数进度效果

    文章目录 前言 先看效果图 ![在这里插入图片描述](https://img-blog.csdnimg.cn/6e4ddec17933496ea4830fa08d8ffbe5.png?x-oss-pr ...

  3. 自定义View之仿QQ运动步数进度效果

    前言 今天接着上一篇来写关于自定义View方面的东西,我是近期在学习整理这方面的知识点,所以把相关的笔记都放到这个Android自定义View的专栏里了,方便自己下次忘记的时候能回来翻翻,今天的内容是 ...

  4. 自定义 View 之仿 QQ 步数变动动画效果

    博主声明: 转载请在开头附加本文链接及作者信息,并标记为转载.本文由博主 威威喵 原创,请多支持与指教. 本文首发于此   博主:威威喵  |  博客主页:https://blog.csdn.net/ ...

  5. [VSTO系列]二、简单的UI设计/QQ联系人导出(上)

    接上一篇:http://www.cnblogs.com/longqi293/archive/2010/12/08/vstoforexcel1.html 在日常的生活中,QQ已经是联系我们人际关系的一条 ...

  6. 安卓仿苹果音量调节_android自定义view仿照MIUI中音量控制效果

    先看效果图: 这就是miui中的音量效果图,实现思路是自定义视图,绘制圆环,然后设置进度显示. 核心代码在onDraw中实现如下: @Override protected void onDraw(Ca ...

  7. android取QQ昵称,Android仿QQ复制昵称效果

    背景: 这几天做一个复制文本的需求,突然看到QQ上复制昵称跟QQ号的效果,觉得很不错,就想要模仿一波,办法比较简单粗暴,反编译QQ获取了那个.9图片,然后就是用PopWindow实现了. 解决办法: ...

  8. android代码实现手机加速功能,Android自定义View实现内存清理加速球效果

    Android自定义View实现内存清理加速球效果 发布时间:2020-09-21 22:21:57 来源:脚本之家 阅读:105 作者:程序员的自我反思 前言 用过猎豹清理大师或者相类似的安全软件, ...

  9. java 树 右键菜单_jQuery实现自定义右键菜单的树状菜单效果

    本文实例讲述了jQuery实现自定义右键菜单的树状菜单效果.分享给大家供大家参考.具体如下: 这是一款基于jQuery的自定义右键菜单,在树状结构的子节点(下级没有节点)上单击右键才会弹出自定义菜单, ...

最新文章

  1. Go 学习笔记(33)— Go 自定义类型 type(自定义结构体、结构体初始化、结构体内嵌、自定义接口)
  2. win7访问不了服务器共享文件夹权限设置,win7系统开启共享文件夹访问权限的操作方法...
  3. Flink源码分析 - 源码构建
  4. 六种方法,做一名更好的开发者
  5. Linux 内核自旋锁
  6. Python分析年度爆款“网抑云”热评,看看哪些文案触动了你的内心世界?
  7. 滴滴新规则明日起试行:将影响一大波人
  8. PyTorch 深度学习:36分钟快速入门——GAN
  9. hive元数据为什么使用Mysql?不使用默认的Derby
  10. 如何在本机安装mysql_机器人之如何在本机安装MySQL,并配置电脑为数据库服务器...
  11. 一篇文章看懂什么是无服务器架构
  12. Unity3D 多层血条特效
  13. 前端开发,测试,后端,该如何选择?
  14. 利用计算机辅助药物设计方法有何优点,计算机辅助药物设计的原理及应用
  15. 四川麻将java_四川麻将纯AI算法------最优拆牌
  16. 美国网络再次“瘫痪”,华为意外“出头”,网络服务器世界第一
  17. html 导航栏颜色代码,CSS实现五颜六色按钮组成的导航条效果代码
  18. cadence 提示lic找不到怎么办
  19. 电脑版微信文件存储在哪个文件夹可以找到
  20. 心率检测实现报告(一)

热门文章

  1. 如何测试光盘的质量?
  2. Linux快捷键总结
  3. 福州古刹梅林尽染 林阳赏梅成闽都新俗
  4. ben we_老WE成立手游战队!2020LOL冬季转会汇总:截止11月17日(每日更新)
  5. 2021高考汇文中学成绩查询,2021年北京高考英语阅读理解评析(北京汇文中学)...
  6. Python 中的三元运算符,三目表达式
  7. 【转】JavaScript入门学习书籍的阶段选择——BY怿飞
  8. Framework学习(五)应用程序启动过程
  9. 《谍影重重4》虎头蛇尾
  10. Invertible Denoising Network: A Light Solution for Real Noise Removal