本Demo仅供参考,不做任何商业用途,转载请附上原文地址!大神指点请勿附带可能被屏蔽的语言!
先上图
我要一个类似于小米通讯录的界面实现,功能点分为以下几个
(1) 以字母为标题的组合二级列表,及侧边首拼音选择
二级列表此处使用两个ListView来实现
第一级显示标题
第二级显示联系人Item
侧边首拼音选择使用ListView注意这里在主Activity的描述文件里面一定要使用Rel...布局,且首字母选择的ListView要放在二级列表之后,不知道为啥你可以试试
(2)实现悬浮替换
实现悬浮替换么,这个也不算太困难,只要监听滚动就行了
ListView为我们提供了setOnScrollListener这监听方法,里面包含了OnScrollListener这个监听接口.
该接口内部提供两个方法onScrollStateChanged()监听新的滚动状态(这个就不多说了,暂时用不上)
onScroll这个在源码里面的注释是 滚动侦听器(通知我们的滚动时(如果有的话)改变的滚动状态),
而firstVisibleItem参数很重要,他是判断当前滚动时处于哪一个Item而我们的悬浮和首字母状态改变都是依赖于他做成的
(3)实现侧边首字母选项当,上一字母标题消失的时候,改变正在显示的第一个单词字体的颜色
不多说了上代码
主Activitypublic class MainActivity extends Activity { String[] arr = {"☆","A","B","C","D","E","F","G","H","I","J","K","L","M" ,"N","O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y" , "Z"}; private String result; private ListView listview; private TextView tv_tit; private List<SZMUtils> list; private SZMAdapter szmadapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); handler.sendEmptyMessage(1); //初始控件 initView(); } int dqposinit = -1; private void initView() { tv_tit = (TextView) findViewById(R.id.tv_tit); listview = (ListView) findViewById(R.id.listview); //监听二级列表的滚动状态 listview.setOnScrollListener(new MySroll()); ListView zm_name = (ListView) findViewById(R.id.zm_name); szmadapter = new SZMAdapter(MainActivity.this,arr); zm_name.setAdapter(szmadapter); //监听首字母的点击事件,并改变状态 zm_name.setOnItemClickListener(new MyOnItemClick()); } Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what){ case 1: setUI(); break; } } }; private void setUI() { //获取数据,可以讲数据从ListView嵌套Map集合的结构转换成二级列表的结构 list = JSonUtils.pasonJson(result); LXRAdapter lxrAdapter = new LXRAdapter(list,MainActivity.this); listview.setAdapter(lxrAdapter); //数据加载完了告诉他更新边上的字母选中状态 szmadapter.setItem(list.get(0).getName()); } public class MySroll implements AbsListView.OnScrollListener { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { /* ListView的滚动监听 */ Log.i("zxzx",firstVisibleItem + " "+visibleItemCount+" "+totalItemCount); if (firstVisibleItem >= 1) { tv_tit.setText(list.get(firstVisibleItem).getName()); tv_tit.setVisibility(View.VISIBLE); } else { tv_tit.setVisibility(View.GONE); } //这个鬼的滚动监听里也要改变字母的状态 //但是那,这玩意改变时要做个判断,不信的话你滚动的时候打印下看看上面的三个参数就知道了 if(dqposinit!=firstVisibleItem){ dqposinit = firstVisibleItem; // Log.i("zxzxzone",firstVisibleItem+" x??"); if(firstVisibleItem!=0) { //改变首字母侧选栏的状态 szmadapter.setItem(list.get(firstVisibleItem).getName()); //滑动时的实时弹窗,暂时没有思路,先放着吧 } } } } public class MyOnItemClick implements AdapterView.OnItemClickListener { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { String par = arr[position]; for(int i = 0;i<list.size();i++){ if(list.get(i).getName().equals(par)){ //点击侧边栏字母,改变对应的状态 szmadapter.setItem(par); listview.setSelection(i); } } } } }
布局文件<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.dialog.myapplications.MainActivity"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:scrollbars="none" android:divider="@null" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/listview"></ListView> </RelativeLayout> <ListView android:scrollbars="none" android:layout_marginTop="35dp" android:divider="@null" android:id="@+id/zm_name" android:layout_width="15dp" android:layout_marginRight="10dp" android:layout_height="match_parent" android:layout_alignParentRight="true" ></ListView> <TextView android:paddingLeft="5dp" android:layout_width="match_parent" android:layout_height="35dp" android:id="@+id/tv_tit" android:visibility="gone" android:gravity="center_vertical" android:text="666" android:background="@color/wheel_timebtn_pre"/> </RelativeLayout>
一级列表,二级列表的标题
public class LXRAdapter extends BaseAdapter { List<SZMUtils> list; Context context; public LXRAdapter(List<SZMUtils> list, Context context) { this.list= list; this.context= context; } @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { MyViewHolder myViewHolder ; if(convertView==null){ myViewHolder = new MyViewHolder(); convertView = View.inflate(context,R.layout.item_lay,null); myViewHolder.tv = (TextView) convertView.findViewById(R.id.zxsname); myViewHolder.list_items = (ListView) convertView.findViewById(R.id.list_items); convertView.setTag(myViewHolder); }else{ myViewHolder = (MyViewHolder) convertView.getTag(); } myViewHolder.tv.setText(list.get(position).getName()); LXRAdapters lxrAdapters = new LXRAdapters(list.get(position).getList(),context); myViewHolder.list_items.setAdapter(lxrAdapters); Log.i("zzxx",list.get(position).getList().size()+" XZ"); ViewGroup.LayoutParams layoutParams = myViewHolder.list_items.getLayoutParams(); layoutParams.height = 183*list.get(position).getList().size(); myViewHolder.list_items.setLayoutParams(layoutParams); return convertView; } class MyViewHolder{ TextView tv; ListView list_items; } }
二级列表
public class LXRAdapters extends BaseAdapter implements View.OnClickListener { public String IMGHOST = "https://guanshi.51oses.com/Public/images/img/m_"; List<RenYuan> list; Context context; private final MyBitmapUtils myBitmapUtils; private View v; public LXRAdapters(List<RenYuan> list, Context context) { this.list = list; this.context =context; myBitmapUtils = new MyBitmapUtils(context); } @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { MyViewHH myViewHH; if(convertView==null) { myViewHH = new MyViewHH(); convertView = View.inflate(context, R.layout.lxr_item, null); myViewHH.iv_image = (ImageView) convertView.findViewById(R.id.image); myViewHH.tv_name = (TextView) convertView.findViewById(R.id.name); v = convertView.findViewById(R.id.view); myViewHH.tv_phone = (TextView) convertView.findViewById(R.id.phone); myViewHH.linn = (LinearLayout) convertView.findViewById(R.id.linn); myViewHH.linn.setTag(position); myViewHH.linn.setOnClickListener(this); convertView.setTag(myViewHH); }else{ myViewHH = (MyViewHH) convertView.getTag(); } if(position==0){ v.setVisibility(View.GONE); } if(list.get(position).getImage().endsWith("jpg")||list.get(position).getImage().endsWith(".jpeg")||list.get(position).getImage().endsWith(".png")) { myBitmapUtils.display(myViewHH.iv_image, IMGHOST + list.get(position).getImage()); }else{ myViewHH.iv_image.setImageDrawable(context.getResources().getDrawable(R.drawable.touxiang)); } myViewHH.tv_name.setText(list.get(position).getName()); myViewHH.tv_phone.setText(list.get(position).getPhone()); // Log.i("zxzzx",list.get(position).getName()+" "+list.get(position).getPhone()); return convertView; } @Override public void onClick(View v) { int z = (int) v.getTag(); switch (v.getId()){ case R.id.linn: Intent intent = new Intent(context,Log.class); intent.putExtra("uid",list.get(z).getUid()); context.startActivity(intent); break; } } class MyViewHH{ LinearLayout linn; ImageView iv_image; TextView tv_name; TextView tv_phone; } }
详情请参见DEMO,源码下载地址点我点我点我就行了!没毛病老铁!