openfire+smack使用ListFragment加载好友列表

在Activity中加载自定义ListView的时候,需要自定义适配器类继承BaseAdapter类,但Fragment中使用自定义的ListView,则使用ListFragment来实现和SimpleAdapter适配器。

效果图:

                 

一、使用ListFragment加载好友列表实现思路

1、编写ListFragment的布局文件fragment_two.xml,其中定义好ListView的位置,且ListView的id必须定义为android:list

2、编写子定义ListView的每个项布局文件fragment_two_item.xml

3、编写Fragment2.java类继承ListFragment类,使用SimpleAdapter适配器适配ListView内容,ListViewitem点击事件跳转到指定好友聊天界面。

二、功能具体实现

1、ListFragment的布局文件fragment_two.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <LinearLayout 
        android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:background="@drawable/linearlayout_boder"
		>
	    <LinearLayout 
		    android:layout_width="fill_parent"
		    android:layout_height="wrap_content"
		    android:layout_marginTop="5dp"
		    android:layout_marginBottom="5dp"
		    android:orientation="horizontal" 
		    android:background="#FFF"
		    >
		    <ImageView 
		        android:layout_width="40dp"
		        android:layout_height="40dp"
		        android:layout_marginLeft="5dp"
		        android:layout_gravity="center_vertical"
		        android:background="@drawable/newfriend"
		        />
		  	<TextView 
		        android:layout_width="match_parent"
		        android:layout_height="wrap_content"
		        android:layout_gravity="center_vertical"
		        android:gravity="center_vertical"
		        android:layout_marginLeft="5dp"
		        android:textSize="18sp"
		        android:textStyle="bold" 
		        android:text="新朋友"
		        />  
		</LinearLayout>
	</LinearLayout>
	
    <LinearLayout 
        android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:background="@drawable/linearlayout_boder"
		>
	    <LinearLayout 
		    android:layout_width="fill_parent"
		    android:layout_height="wrap_content"
		    android:layout_marginTop="5dp"
		    android:layout_marginBottom="5dp"
		    android:orientation="horizontal"
		    android:background="#FFF" >
		    <ImageView 
		        android:layout_width="40dp"
		        android:layout_height="40dp"
		        android:layout_marginLeft="5dp"
		        android:layout_gravity="center_vertical"
		        android:background="@drawable/grouptalk"
		        />
		  	<TextView 
		        android:layout_width="match_parent"
		        android:layout_height="wrap_content"
		        android:layout_gravity="center_vertical"
		        android:gravity="center_vertical"
		        android:layout_marginLeft="5dp"
		        android:textSize="18sp"
		        android:textStyle="bold" 
		        android:text="群聊"
		        />  
		</LinearLayout>
	</LinearLayout>
    
    <LinearLayout 
        android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:background="@drawable/linearlayout_boder"
		>
	    <LinearLayout 
		    android:layout_width="fill_parent"
		    android:layout_height="wrap_content"
		    android:layout_marginTop="5dp"
		    android:layout_marginBottom="5dp"
		    android:orientation="horizontal" 
		    android:background="#FFF">
		    <ImageView 
		        android:layout_width="40dp"
		        android:layout_height="40dp"
		        android:layout_marginLeft="5dp"
		        android:layout_gravity="center_vertical"
		        android:background="@drawable/tips"
		        />
		  	<TextView 
		        android:layout_width="match_parent"
		        android:layout_height="wrap_content"
		        android:layout_gravity="center_vertical"
		        android:gravity="center_vertical"
		        android:layout_marginLeft="5dp"
		        android:textSize="18sp"
		        android:textStyle="bold" 
		        android:text="标签"
		        />  
		</LinearLayout>
	</LinearLayout>
    <ListView 
        android:id="@+id/android:list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        ></ListView>

</LinearLayout>
2、ListView的每个项布局文件fragment_two_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/linearlayout_boder">
	<LinearLayout 
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
	    android:layout_marginTop="5dp"
	    android:layout_marginBottom="5dp"
	    android:orientation="horizontal" >
	    <ImageView 
	        android:id="@+id/tab2_item_img"
	        android:layout_width="40dp"
	        android:layout_height="40dp"
	        android:layout_marginLeft="5dp"
	        android:layout_gravity="center_vertical"
	        />
	  	<TextView 
	        android:id="@+id/tab2_item_name"
	        android:layout_width="match_parent"
	        android:layout_height="wrap_content"
	        android:layout_gravity="center_vertical"
	        android:gravity="center_vertical"
	        android:layout_marginLeft="5dp"
	        android:textSize="18sp"
	        android:textStyle="bold" 
	        />  
	</LinearLayout>
</LinearLayout>
3、主界面Fragment2.java

package com.example.eric_jqm_chat;

import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.provider.ProviderManager;
import org.jivesoftware.smackx.packet.VCard;

import com.example.eric_jqm_chat.TabFragment.UserAndPasswordOne;

import android.app.Activity;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.ListFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.SimpleAdapter.ViewBinder;
import android.widget.Toast;

public class TabFragment2 extends ListFragment {
	//创建连接对象
	private XMPPConnection con = new ConnectServer().ConnectServer();
	//获得接口实例,该接口用来获取从前一个Activity传来的登录用户的用户名和密码
	private UserAndPasswordTwo mUserAndPassword;
	private String name ,password;
	//Roster对象,可以通过Roster对象实例后进行获取好友列表
	private Roster roster;
	
	@Override
	public View onCreateView(LayoutInflater inflater,
			@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
		//加载Fragment2的布局文件
		return inflater.inflate(R.layout.fragment_two, container, false);
	}
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		//定义键名称和指定控件id
		final String[] str = new String[]{"img","name"};
		final int[] id = new int[]{R.id.tab2_item_img,R.id.tab2_item_name};
		
		super.onCreate(savedInstanceState);
		
		//获取用户名和密码,该方法在前面的博文:Activity与Fragment相互传递参数 
		//有介绍,这里不再赘述
		name = mUserAndPassword.getUserTwo(name);
		password = mUserAndPassword.getPasswordTwo(password);
		//登录用户
		try {
			con.login(name, password);
		} catch (XMPPException e) {
			e.printStackTrace();
		}
		
		//使用SimpleAdapter进行适配ListView内容
		SimpleAdapter adapter = new SimpleAdapter(getActivity(), getSimpleData(), 
				R.layout.fragment_two_item, str, id);
		this.setListAdapter(adapter);
		
		//SimpleAdapter只能为控件适配drawable目录下的图片即R.drawable.XX
		//为了适应我们从服务器获取的Drawable类型图片,必须使用到ViewBinder类
		adapter.setViewBinder(new ViewBinder() {
			@Override
			public boolean setViewValue(View view, Object data, String arg2) {
				if(view instanceof ImageView && data instanceof Drawable){
					ImageView iv = (ImageView)view;
					iv.setImageDrawable((Drawable)data);
					return true;
				}else{
					return false;
				}
			}    
        });   
		 
	} 
	
	//获取ListView适配的数据类
	private List<Map<String,Object>> getSimpleData(){
		List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
		
		//实例化Roster对象
		roster = con.getRoster();
		//通过getallEntries()获取Roster对象的好友列表
		List<RosterEntry> friendList = this.getallEntries(roster);
		//创建键值对
		Map<String, Object> map = new HashMap<String, Object>();
		//
		for(int i=0;i<friendList.size();i++){
			map = new HashMap<String, Object>();
			map.put("name",friendList.get(i).getName());
			//从服务器获取好友头像
			Drawable imgDrawable =  this.getUserImage(con, friendList.get(i).getName());
			//若用户未设置头像则使用本地默认头像
			if(imgDrawable == null){
				map.put("img", R.drawable.user);
			}else{
				map.put("img", imgDrawable);
			}
			list.add(map);
		}
		//System.out.println("list===="+list);
		return list;
		
	}
	
	
	//ListView点击事件
	@Override
	public void onListItemClick(ListView l, View v, int position, long id) {
		Toast.makeText(getActivity(), "Select"+position, Toast.LENGTH_SHORT).show();
			//获取点击位置ListView项键名为name的值,即好友的用户名
			Map<String,Object> m = getSimpleData().get(position);
			Iterator it = m.keySet().iterator();
			Object o = m.get("name");
			String friend = o.toString();
			//System.out.println("friend=="+friend);
			
			//进行页面跳转,并传值给ChatActivity,包括用户名密码,好友名
			Intent intent = new Intent();
			intent.setClass(getActivity(),ChatActivity.class);
			intent.putExtra("friend", friend);
			intent.putExtra("name", name);
			intent.putExtra("password", password);
			startActivity(intent);
		
		super.onListItemClick(l, v, position, id);
	}
	
	//获取Activity传来的用户名密码的接口声明
	public interface UserAndPasswordTwo {
		public String getUserTwo(String user);
		public String getPasswordTwo(String password);
	}
	
	@Override
	public void onAttach(Activity activity) {
		
		super.onAttach(activity);
		try {
			mUserAndPassword = (UserAndPasswordTwo) activity;
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("接口实例化异常");
		}
		
	}
	
	//查询所有好友信息
    public  List<RosterEntry> getallEntries(Roster roster) {  
        List<RosterEntry> Entrieslist = new ArrayList<RosterEntry>();  
        Collection<RosterEntry> rosterEntry = roster.getEntries();  
        Iterator<RosterEntry> i = rosterEntry.iterator();  
        while (i.hasNext()) {  
            Entrieslist.add(i.next());  
        }  
        return Entrieslist;  
    } 
    
    //获取指定用户头像类
    public Drawable getUserImage(XMPPConnection con,String user) {  
    	ByteArrayInputStream bais =null;
    	
    	if (con == null)  
            return null;  
          
        try {  
            VCard vcard = new VCard();  
            
            ProviderManager.getInstance().addIQProvider("vCard", "vcard-temp",  
            new org.jivesoftware.smackx.provider.VCardProvider()); 
            
            vcard.load(con, user.trim()+"@"+con.getServiceName());
            
            
            if (user == "" || user == null || user.trim().length() <= 0) { 
            	//Toast.makeText(Login.this, "user为空", 0).show();
                return null;  
            }  

            if (vcard == null || vcard.getAvatar() == null){
            	//Toast.makeText(Login.this, "Vcard为空", 0).show();
            	return null;  
            }
            
            bais = new ByteArrayInputStream(vcard.getAvatar());
            
        } catch (Exception e) {  
            e.printStackTrace(); 
           // Toast.makeText(Login.this, "图片获取异常"+e, 0).show();
           // System.out.println("图片获取异常: "+e);
            return null;  
        }  
        return FormatTools.getInstance().InputStream2Drawable(bais);  
    }
}
4、聊天界面ChatActivity.java

package com.example.eric_jqm_chat;
//聊天界面ChatActivity的详细制作在前面的博文:openfire+smack聊天气泡效果ListView完成收发消息
//有详细介绍,本章就主要描述从Fragment传过来的值怎么使用
//首先使用获得的用户名密码登录,获得自己的头像,根据好友们获得好友头像
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;

import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManagerListener;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Message;



import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;

/*
 *@author  Eric
 *@create date 2015-8-25下午8:51:17
 */

public class ChatActivity extends Activity {
	private TextView text_chat,text_title;
	private EditText edit_chat;
	private ImageView img_send;
	private Drawable img_userDrawable,img_friendDrawable;
	private XMPPConnection con = new ConnectServer().ConnectServer();
	private String str_text,name,password,friend,sendMsg;
	private ChatHandler handler;
	private SimpleDateFormat sf = new SimpleDateFormat("HH:mm");
	
	private ArrayList<HashMap<String, Object>> chatList = new ArrayList<HashMap<String,Object>>();
	String[] from = {"img","text"};
	int[] to = {R.id.img_me,R.id.text_me,R.id.img_friend,R.id.text_friend};
	int[] item_layout = {R.layout.i_sendmsg_item,R.layout.friend_sendmsg_item};
	private ListView listview_chat;
	private MyAdapter myAdapter;
	
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.chat);
		
		img_send = (ImageView) findViewById(R.id.img_send);
		edit_chat = (EditText) findViewById(R.id.edit_chat);
		listview_chat = (ListView) findViewById(R.id.listview_chat);
		text_title = (TextView) findViewById(R.id.text_title);
		
		
		myAdapter = new MyAdapter(this, chatList, item_layout, from, to);
		
		//获取从Fragment传过来的值
		name = getIntent().getStringExtra("name");
		password = getIntent().getStringExtra("password");
		friend = getIntent().getStringExtra("friend");
		text_title.setText(friend);
		try {
			con.login(name, password);
		} catch (XMPPException e) {
			e.printStackTrace();
		}
		
		//获取用户头像和好友头像
		img_userDrawable = new TabFragment2().getUserImage(con, name);
		img_friendDrawable = new TabFragment2().getUserImage(con, friend);
		
		img_send.setOnClickListener(new OnClickListener() {
					
			@Override
			public void onClick(View arg0) {
				sendMsg = edit_chat.getText().toString();		
				
				Chat chat = con.getChatManager().createChat(friend+"@"+"eric-pc", null);
				try {
					chat.sendMessage(sendMsg);
				} catch (XMPPException e) {
					e.printStackTrace();
				}
				
				edit_chat.setText(null);
				
				addChatToListview(0, sendMsg);
				
				//将ListView设置为置底显示,自动刷新UI,使得消息及时显示
				listview_chat.setAdapter(myAdapter);
				listview_chat.setSelection(myAdapter.getCount()-1);
			}
		});
		
		//监听用户接收到的消息的副线程
		Thread thread = new Thread(new Runnable(){

			@Override
			public void run() {
				//接收用户发来的消息
				con.getChatManager().addChatListener(new ChatManagerListener() {
					
					@Override
					public void chatCreated(Chat chat, boolean arg1) {
						chat.addMessageListener(new MessageListener() {
							
							@Override
							public void processMessage(Chat chat, Message msg) {
								
								friend = msg.getFrom();
								friend = friend.substring(0, friend.indexOf("@"));
								 
								android.os.Message m = new android.os.Message();
								if(msg.getBody()!= null){
									Bundle b= new Bundle();
									b.putString("msg", msg.getBody());
									b.putString("friend", friend);
									m.setData(b);
									handler.sendMessage(m);
								}
								
								 
							}
						});
					}
				});
				
				
				
			}
			
		});
		
		thread.start();
		handler = new ChatHandler();
		
		
	}
	
	
	public class ChatHandler extends Handler{
		@Override
		public void handleMessage(android.os.Message msg) {
			super.handleMessage(msg);
			
			Bundle b = msg.getData();
			String ChatHandler = b.getString("msg");
			String friend = b.getString("friend");
			
			text_title.setText(friend);
			addChatToListview(1, ChatHandler);
			
			//将ListView设置为置底显示,自动刷新UI,使得消息及时显示
			listview_chat.setAdapter(myAdapter);
			listview_chat.setSelection(myAdapter.getCount()-1);
			
		}
	}
	
	
	public void addChatToListview(int who,String chat){
		HashMap<String,Object> map = new HashMap<String,Object>();
		map.put("who", who);
		map.put("img", who==0?R.drawable.touxiang1:R.drawable.touxiang5);
		map.put("chat", chat);
		chatList.add(map);
	}
	
	
	public class MyAdapter extends BaseAdapter{
		Context context;
		ArrayList<HashMap<String,Object>> chatList= null;
		int[] layout;
		String[] from;
		int[] to;
		LayoutInflater listcontainer;
		
		public MyAdapter(Context context,
                ArrayList<HashMap<String, Object>> chatList, int[] layout,
                String[] from, int[] to){
			
	        super();
	        this.context = context;
	        listcontainer = LayoutInflater.from(context);
	        this.chatList = chatList;
	        this.layout = layout;
	        this.from = from;
	        this.to = to;
		}
		
		@Override
		public int getCount() {
			return chatList.size();
		}

		@Override
		public Object getItem(int arg0) {
			return null;
		}

		@Override
		public long getItemId(int ItemId) {
			return ItemId;
		}
		
		
		@Override
		public View getView(int item, View view, ViewGroup parent) {
			//获取当前子项的who和chat
            int who = (Integer)chatList.get(item).get("who"); 
            String msg = (String)chatList.get(item).get("chat");
            //根据who设置当前子项的布局和文本,0为自己发送的布局,1为好友发送的布局
            if(who==0)  
            {  
            	view=listcontainer.inflate(R.layout.i_sendmsg_item, null);  
                ((TextView)view.findViewById(R.id.text_me)).setText(msg);  
                ((ImageView)view.findViewById(R.id.img_me)).setImageDrawable(img_userDrawable);  
                return view;  
            }  
            else  
            {  
            	view=listcontainer.inflate(R.layout.friend_sendmsg_item, null);  
                ((TextView)view.findViewById(R.id.text_friend)).setText(msg);  
                ((ImageView)view.findViewById(R.id.img_friend)).setImageDrawable(img_friendDrawable);  
                return view;  
            }  
		}
		
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值