仿写 QQ 和 微信 联系人列表:
来源:互联网 发布:云计算和云存储的区别 编辑:程序博客网 时间:2024/05/19 16:38
QQ聊天联系人界面效果仿写:
1,先上效果图 ,因为未找到 比较好用的 gif录制工具 。所以上的都是静态图片:
2,代码:
主界面: 两个 Fragment交互:
class MainActivity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener { RadioGroup group; private Fragment[] fragments; private FragmentManager fm; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); group = (RadioGroup) findViewById(R.id.group); fm = getSupportFragmentManager(); if (savedInstanceState == null) { fragments = new Fragment[2]; fragments[0] = QQContactsFragment.newInstance(); fragments[1] = WeChatContactsFragment.newInstance(); FragmentTransaction tx = fm.beginTransaction(); for (int i = 0; i < fragments.length; i++) { tx.add(R.id.container, fragments[i], "fragment" + i); } tx.commit(); } else { for (int i = 0; i < fragments.length; i++) { fragments[i] = fm.findFragmentByTag("fragment" + i); } } group.setOnCheckedChangeListener(this); group.check(R.id.QQDemo); } @Override public void onCheckedChanged(RadioGroup group, int checkedId) { int index = 0; switch (checkedId) { case R.id.QQDemo: index = 0; break; case R.id.weChatDemo: index = 1; break; default: break; } FragmentTransaction tx = fm.beginTransaction(); for (int i = 0; i < fragments.length; i++) { if (index == i){ tx.show(fragments[i]); }else{ tx.hide(fragments[i]); } } tx.commit(); }}
QQ 联系人界面适配器:比较简单:直接reCycle 适配 设置分组数据显示和不显示:
package com.hero.zhaoq.qqgitdemo.adapters;import android.content.Context;import android.support.annotation.Nullable;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.TextView;import android.widget.Toast;import com.hero.zhaoq.qqgitdemo.R;import com.hero.zhaoq.qqgitdemo.domain.Contact;import com.hero.zhaoq.qqgitdemo.utils.CollectionsUtils;import java.util.HashMap;import java.util.List;/** * author: zhaoqiang * date:2017/10/13 / 15:45 * zhaoqiang:zhaoq_hero@163.com */public class MQQADapter extends RecyclerView.Adapter<MQQADapter.ViewHolder> { private HashMap<String, List<Contact>> dataMaps; private List<String> keys; private List<List<Contact>> values; private Context context; public MQQADapter(Context context, @Nullable HashMap<String, List<Contact>> dataMaps) { this.context = context; this.dataMaps = dataMaps; if (dataMaps != null) { keys = CollectionsUtils.getKeysListFromMap(dataMaps); values = CollectionsUtils.getValueListFromMap(dataMaps); } } @Override public int getItemCount() { return keys == null ? 0 : keys.size(); } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View itemView = LayoutInflater.from(context).inflate(R.layout.item_depatment_list, null, false); return new ViewHolder(itemView); } @Override public void onBindViewHolder(ViewHolder holder, int position) { holder.setData(position); } public void setNewData(HashMap<String, List<Contact>> departmentEntityList) { this.dataMaps = departmentEntityList; if (dataMaps != null) { keys = CollectionsUtils.getKeysListFromMap(dataMaps); values = CollectionsUtils.getValueListFromMap(dataMaps); } notifyDataSetChanged(); } public class ViewHolder extends RecyclerView.ViewHolder { private TextView title, count; private ImageView arrowImg; private LinearLayout list_view; private View titleLayout; public ViewHolder(View itemView) { super(itemView); title = (TextView) itemView.findViewById(R.id.parent_title); count = (TextView) itemView.findViewById(R.id.num_count); arrowImg = (ImageView) itemView.findViewById(R.id.arrow); list_view = (LinearLayout) itemView.findViewById(R.id.list_view); titleLayout = itemView.findViewById(R.id.title_layout); } public void setData(int position) { //绑定数据 title.setText(keys.get(position));//部门名称 count.setText("(" + values.get(position).size() + ")人"); initListView(list_view, values.get(position)); titleLayout.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { boolean isopen = titleLayout.getTag() == null ? false : (boolean) titleLayout.getTag(); list_view.setVisibility(isopen ? View.GONE : View.VISIBLE); arrowImg.setImageResource(!isopen ? R.mipmap.icon_arrow_down : R.mipmap.icon_arrow_left); titleLayout.setTag(!isopen); } }); } } //初始化 内部 listView private void initListView(LinearLayout list_view, List<Contact> userEntities) { if (list_view != null) list_view.removeAllViews(); //循环 绑定数据 for (final Contact item : userEntities) { View itemView = LayoutInflater.from(context).inflate(R.layout.item_conts_and_dept_list, null, false); //绑定数据: ((TextView) itemView.findViewById(R.id.name)).setText(item.getName()); (itemView.findViewById(R.id.tv_section)).setVisibility(View.GONE); itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //打开 联系人详情界面: Toast.makeText(context, "点击了Item:" + item.toString(), Toast.LENGTH_SHORT).show(); } }); list_view.addView(itemView); } } public void onDestory() { dataMaps = null; keys = null; values = null; }}
微信界面适配器:
/** * author: zhaoqiang * date:2017/10/13 / 17:49 * zhaoqiang:zhaoq_hero@163.com */public class MWeChatContsListAdapter extends RecyclerView.Adapter<MWeChatContsListAdapter.ViewHolder> { private List<Contact> data; private Context context; public MWeChatContsListAdapter(Context context, @Nullable List<Contact> data) { this.data = data; this.context = context; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View itemView = LayoutInflater.from(context).inflate(R.layout.item_conts_and_dept_list, null, false); return new ViewHolder(itemView); } @Override public void onBindViewHolder(MWeChatContsListAdapter.ViewHolder holder, final int position) { holder.setData(position); holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(context, data.get(position).toString(), Toast.LENGTH_SHORT).show(); } }); } @Override public int getItemCount() { return data == null ? 0 : data.size(); } public void setNewData(List<Contact> data) { this.data.addAll(data); notifyDataSetChanged(); } public List<Contact> getData() { return this.data; } public class ViewHolder extends RecyclerView.ViewHolder { private TextView name, section; public ViewHolder(View itemView) { super(itemView); name = (TextView) itemView.findViewById(R.id.name); section = (TextView) itemView.findViewById(R.id.tv_section); } //--- public void setData(int position) { name.setText(data.get(position).getName()); if (position == getPositionForSection(data.get(position).getPinyinElement().getPinyin().substring(0, 1).toUpperCase().charAt(0))) { section.setVisibility(View.VISIBLE); section.setText(data.get(position).getPinyinElement().pinyin.substring(0, 1).toUpperCase().charAt(0) + ""); } else { section.setVisibility(View.GONE); } } } public int getPositionForSection(char section) { for (int index = 0; index < data.size(); index++) { Contact contact = data.get(index); if (section == contact.getPinyinElement().pinyin.substring(0, 1).toUpperCase().charAt(0)) { return index; } } return -1; } /** * 根据 大写字母 判断 recycleView 滑动位置: */ public int getRecyListPosition(String upCase) { if (CollectionsUtils.isNoEmpty(this.data)) for (int index = 0; index < this.data.size(); index++) { Contact userEntity = this.data.get(index); if (upCase.equals(userEntity.getPinyinElement().pinyin.substring(0, 1).toUpperCase().charAt(0) + "")) { return index; } } return -1; } public void onDestory() { this.data = null; }}
侧边 字母索引适配器: 侧边索引 以及侧边索引通过 touchEvent 事件判断 并完成界面dialog的显示以及消失:
public class MUpCaseListAdapter extends BaseAdapter { private final Context context; private String[] data = null; public MUpCaseListAdapter(Context mContext) { this.context = mContext; data = context.getResources().getStringArray(R.array.up_case_array); } @Override public int getCount() { return data.length; } @Override public Object getItem(int position) { return data[position]; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) convertView = LayoutInflater.from(context).inflate(R.layout.text_view,null,false); TextView itemView = (TextView) convertView.findViewById(R.id.up_case_txt); itemView.setEnabled(false); itemView.setText(data[position]); //重置 高度: item 高度为屏幕 的0.7 / 27 个字母 convertView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) ((DimensUtils.getScreenSize(context)[1] * 0.7) / 27))); return convertView; } public int getListIndectorPosition(String upCase) { return CollectionsUtils.Strs2AList(data).indexOf(upCase); }}
检测 侧边索引的事件:
侧边索引其实是个listView,通过listView的 onTouchEvent 事件 判断 是否显示中间字母的 dialog。 :
listIndictor.setOnTouchListener(new View.OnTouchListener() { float itemH; float listHeightY; @Override public boolean onTouch(View v, MotionEvent event) { if (swipeToLoadLayout.isRefreshing()) swipeToLoadLayout.setRefreshing(false); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: listIndictor.setBackgroundColor(getResources().getColor(R.color.line_strong_divider)); listHeightY = listIndictor.getMeasuredHeight(); itemH = listHeightY / 27; if (caseIndexDialog == null) { caseIndexDialog = new CaseIndexDialog(getContext()); } caseIndexDialog.show(); break; case MotionEvent.ACTION_MOVE: if (event.getY() < listHeightY && event.getX() >= 0 && event.getY() > 0) { //在移动范围内 计算 当前 点击listView 的位置: int index = (int) (event.getY() / itemH); if (lasView != null) lasView.setEnabled(false); curView = listIndictor.getChildAt(index).findViewById(R.id.up_case_txt); curView.setEnabled(true); lasView = curView; //通知RecycleView 更新 实现联动: String upCase = ((TextView) curView).getText().toString(); //固定滚动位置: if (caseListAdapter.getListIndectorPosition(upCase) != -1) ((LinearLayoutManager) mRecycleView.getLayoutManager()) .scrollToPositionWithOffset(contsListAdapter.getRecyListPosition(upCase), 0); caseIndexDialog.setUpCase(upCase); } break; case MotionEvent.ACTION_UP: listIndictor.setBackgroundColor(getResources().getColor(R.color.translance)); curView.setEnabled(false); caseIndexDialog.dismiss(); break; } return true; } });
Maybe 你更需要下面的 地址:
csdn:http://download.csdn.net/download/u013233097/10022439
github:https://github.com/zqHero/QqGitDemo
如果对你有用 欢迎fork 和star。
阅读全文
0 0
- 仿写 QQ 和 微信 联系人列表:
- 仿QQ联系人列表
- 类QQ,微信,联系人列表搜索UISearchBar使用
- Android 仿QQ和微信发送表情 聊天框架
- Swift3 QQ联系人列表
- 仿写 微信 界面
- iOS开源组件__仿写QQ/微信聊天键盘
- Android实现列表仿联系人快速查找和关键字搜索
- 5、用VB6写的仿QQ列表控件
- 仿Android6.0联系人列表
- Android仿QQ微信开场导航
- Android仿QQ微信开场导航
- 高仿QQ微信相册
- 仿QQ、微信翻页查看聊天记录
- Android 仿QQ/微信语音功能。
- android 仿qq好友列表分组效果及联系人分组效果
- listview侧滑菜单的实现——高仿QQ联系人列表
- listview侧滑菜单的实现——高仿QQ联系人列表
- Codeforces 239C Not Wool Sequences【规律】
- LeetCode 486.Predict the Winner
- 从零开始实现线性回归、岭回归、lasso回归、多项式回归模型
- CF402D Upgrading Array(贪心+数学+线性素数筛)
- 并发工具类—— CountDownLatch
- 仿写 QQ 和 微信 联系人列表:
- SpringCloud 链路追踪应用
- 猜数字小游戏
- git笔记三
- C语言实现链表
- “抓住神经猫”的2D游戏创作
- Java Properties集合 文件清单列表获取
- TensorFlow基础
- 初学者易上手的SSH-struts2 02Action获取表单数据-通配符