samck判断双向好友,显示好友列表

Smack登录,注册,搜索用户,添加双向好友总结

1.ExpandableListView控件的使用

①效果

②相关布局

MainActivity布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical">
    <ExpandableListView
        android:id="@+id/expandable_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>

分组布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:layout_height="40dp">
    <TextView
        android:id="@+id/group_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="水果"
        android:layout_gravity="center_vertical"
        android:paddingLeft="30dp"/>
</LinearLayout>

子分组布局(分组项目)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:layout_height="40dp">
    <TextView
        android:id="@+id/group_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="水果"
        android:layout_gravity="center_vertical"
        android:paddingLeft="30dp"/>
</LinearLayout>

 

③adapter,继承自BaseExpandableListAdapter

class MyExpandableListAdapter:BaseExpandableListAdapter{
    //groups对应java类型String[],表示分组
    //items对应java类型String[][],表示分组下的条目
    //比如groups和items信息如下:
    //group=arrayListOf("fruit","vegetables","drink")
    //items={{"apple","orange","peach","pear"},{"Chinese cabbage","broccoli","tomato"},{"milk","coffee","tear","water")}
    private var groups=ArrayList<String>()
    private var items=ArrayList<ArrayList<String>>()

    constructor(groups:ArrayList<String>,items:ArrayList<ArrayList<String>>,context:Context):super(){
        this.groups.addAll(groups)
        this.items.addAll(items)
    }
    override fun getGroup(groupPosition: Int): Any {
        //返回分组比如:Fruit
        return groups[groupPosition]
    }

    override fun isChildSelectable(groupPosition: Int, childPosition: Int): Boolean {
        return true //item是否可以被选中点击
    }

    override fun hasStableIds(): Boolean {
        return true
    }

    override fun getGroupView(
        groupPosition: Int,
        isExpanded: Boolean,
        convertView: View?,
        parent: ViewGroup?
    ): View {
        //setTag & getTag @see https://www.cnblogs.com/zgqys1980/p/5110882.html
        var mConvertView=convertView
        var groupHolder=GroupHolder()
        if(mConvertView==null){
            mConvertView=LayoutInflater.from(parent!!.context).inflate(R.layout.item_elv_group,parent,false)
            groupHolder.textView=mConvertView.findViewById<TextView>(R.id.group_name)
            mConvertView.setTag(groupHolder)
        }else{
            groupHolder= mConvertView.tag as GroupHolder
        }
        //设置分组名字
        groupHolder.textView?.text=groups[groupPosition]
        //判断是否为展开状态
        if(isExpanded){
            //可以设置展开状态的图标之类的
        }else{
            //可以设置闭合状态的图标
        }
        return mConvertView!!
    }

    override fun getChildrenCount(groupPosition: Int): Int {
        return items[groupPosition].size //具体某个分组里item个数
    }

    override fun getChild(groupPosition: Int, childPosition: Int): Any {
        return items[groupPosition][childPosition]
    }

    override fun getGroupId(groupPosition: Int): Long {
        return groupPosition.toLong()
    }

    override fun getChildView(
        groupPosition: Int,
        childPosition: Int,
        isLastChild: Boolean,
        convertView: View?,
        parent: ViewGroup?
    ): View {
        //和重写getGroupView类似
        var mConvertView=convertView
        var itemHolder:ItemHolder=ItemHolder()
        if(mConvertView==null){
            mConvertView=LayoutInflater.from(parent!!.context).inflate(R.layout.item_elv_item,parent,false)
            itemHolder.textView=mConvertView.findViewById(R.id.item_name)
            mConvertView.tag = itemHolder
        }else{
            itemHolder=mConvertView.tag as ItemHolder
        }
        itemHolder.textView?.text=items[groupPosition][childPosition]
        return mConvertView!!
    }

    override fun getChildId(groupPosition: Int, childPosition: Int): Long {
        return childPosition.toLong()
    }

    override fun getGroupCount(): Int {
        return groups.size //分组个数
    }

    class GroupHolder{
        var textView:TextView?=null
    }
    class ItemHolder{
        var textView:TextView?=null
    }
}

④在MainActivity中初始化数据和为ExpandableListView设置适配器

class MainActivity : AppCompatActivity() {
    private var groups=ArrayList<String>()
    private var items=ArrayList<ArrayList<String>>()
    private var adapter:ExpandableListAdapter?=null
    init{
        this.groups= arrayListOf("fruit","vegetables","drink")
        this.items.add(arrayListOf("apple","orange","peach","pear"))
        this.items.add(arrayListOf("Chinese cabbage","broccoli","tomato"))
        this.items.add(arrayListOf("milk","coffee","tear","water"))
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        //var expandable_lv=findViewById<ExpandableListView>(R.id.expandable_list)
        adapter=MyExpandableListAdapter(groups,items,this)
        //expandable_lv.setAdapter(adapter)
        //error:required ListAdapter!
        //expandable_list.adapter=adapter
        expandable_list.setAdapter(adapter)
    }
}

⑤关于监听事件

//关闭未选中的分组
        expandable_list.setOnGroupExpandListener {
            for(pos in 0 until groups.size){
                if(pos!=it){
                    expandable_list.collapseGroup(pos)
                }
            }
        }
        //分组点击监听
        expandable_list.setOnGroupClickListener(object:ExpandableListView.OnGroupClickListener{
            override fun onGroupClick(
                parent: ExpandableListView?,
                v: View?,
                groupPosition: Int,
                id: Long
            ): Boolean {
                Toast.makeText(this@MainActivity, groups[groupPosition],Toast.LENGTH_SHORT).show()
                return false
            }
        })
        //分组子条目点击监听
        expandable_list.setOnChildClickListener { parent, v, groupPosition, childPosition, id ->
            Toast.makeText(this@MainActivity, items[groupPosition][childPosition],Toast.LENGTH_SHORT).show()
            false
        }

 

⑥注意事项

a.在分组布局中,ExpandableListView默认展开显示向上箭头图标,闭合显示向下箭头图标。分组名所在的TextView应该设置paddingLeft属性,从而与默认图标保持一定距离,否则默认图标和分组名会重合

b.kotlin中,为ExpandableListView设置适配器的时候,使用静态方法 .adapter需要传入一个ListAdapter!类型参数;而使用动态方法setAdapter方法,传入一个ExpandableListAdapter类型参数就可以了。这里使用动态方法

 2.smack判断双向好友

RosterEntry类型的type.name方法如果为“both”则是双向好友

if(TextUtils.equals("both",friend.type.name)){
                    //
                }

3.显示好友列表

可以在RosterManage中定义两个函数

 //获得所有分组
    fun getAllGroup():Collection<RosterGroup>{
        var groups:Collection<RosterGroup> =roster!!.groups
        return groups
    }

    //获得分组好友
    fun getGroupFriends(group:RosterGroup):List<RosterEntry>{
        if (!roster!!.isLoaded) try {
            roster!!.reloadAndWait()
        } catch (e: Exception) {
            e.printStackTrace()
        }
        var friends:List<RosterEntry> =group.entries
        return friends
    }

在activity调用这两个函数初始化gourps和items变量,详细的可以参考ExpandableListView的使用

private var conn:XMPPTCPConnection?=null
    private var rosterManager:RosterManager?=null
    private var adapter: ExpandableListAdapter?=null
    private var groups=ArrayList<String>()
    private var items=ArrayList<ArrayList<String>>()
    init{
        conn=ConnectionManage.smackConnection.getConnection()
        rosterManager=RosterManager(conn!!)
        //获得分组和分组好友
        var rosterGroups:Collection<RosterGroup> =rosterManager!!.getAllGroup()
        var itemList=ArrayList<String>()
        for(group in rosterGroups){
            groups.add(group.name)
            var rosterEntries= rosterManager!!.getGroupFriends(group)
            for(friend in rosterEntries){
                //判断是双向好友~
                if(TextUtils.equals("both",friend.type.name)){
                    itemList.add(friend.name)
                }
            }
            items.add(itemList)
        }
    }

运行:

 

未完成

①传给ExpandableListView的groups不应该是字符串数组(如ArrayList<String>),而应该是对象Group的数组列表,Group可以是自定义的类似于javabean类,用于保存分组的各种信息;

同样items,也应该是类似于ArrayList<ArrayList<Friend>>这样的类型,Friend可以保存好友的头像,签名,用户名,昵称等信息。但是这里省事起见,就用字符串类型只保存其用户名了

②有新好友添加之后,更新数据和控件

参考

ExpandableListView展示二级列表(Kotlin)

ExpandableListView--基本使用介绍

ExpandableListView使用方法详解

Openfire+smack打造IM即时通讯【动脑学院】(第七节)

posted @ 2021-01-06 18:00  vocus  阅读(234)  评论(0编辑  收藏  举报