Fragment实践之聊天窗口

前几天刚学了android的fragment,总是停留在简单的demo,或许永远都学不会。

今天,我要动手向我的聊天软件开刀。今天,用Fragment来实现一个如下图效果的聊天界面。

从图中可以看出,这个activity是由三部分组成:1)抬头,包含一个返回按钮,对话用户的名字和一个对话好友的信息按钮;2)一个聊天的历史记录;3)底部是输入,包含更多丰富的输入按钮,文本输入以及发送按钮。

第一步:定义好资源文件

资源文件主要是布局文件,布局文件所用到的其他资源我们在此就不再做介绍了

new_chat_layout.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:id="@+id/chat_title_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        >
        </LinearLayout>

        <LinearLayout
        android:id="@+id/chat_history_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1.0"
        android:background="@color/white3"
        android:orientation="horizontal">
        </LinearLayout>
            <LinearLayout
        android:id="@+id/chat_bottom_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        </LinearLayout>
            <LinearLayout
        android:id="@+id/chat_multifunc_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        </LinearLayout>

</LinearLayout>

其效果图如下:空白的

接下来,我们创建抬头的fagment的layout文件

frag_chat_title_layout.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="60dip"
        android:background="@drawable/skinpic_blue"
        android:gravity="center_vertical" >

        <ImageButton
            android:id="@+id/title_back"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/title_btn_l_selector"
            android:padding="0.0dip"
            android:src="@drawable/title_btn_back" />

        <TextView
            android:id="@+id/to_chat_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1.0"
            android:ellipsize="end"
            android:gravity="center"
            android:singleLine="true"
            android:textColor="#ffffffff"
            android:textSize="18.0sp"
            android:text="张三"
            android:textStyle="bold" />

        <ImageButton
            android:id="@+id/user_info"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/title_btn_r_selector"
            android:padding="0.0dip"
            android:src="@drawable/popbar_icon_info" />

    </LinearLayout>

其效果如下:

接下来我们定义聊天记录的布局文件

frag_history_list_layout.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="wrap_content"
    android:layout_weight="1.0"
    android:background="@color/white3"
    android:orientation="vertical" >

         <ListView
        android:id="@+id/chat_list"
       android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1.0"
        android:background="@color/white3"
        android:divider="@null"
        android:listSelector="@android:color/transparent"

         /> 

</LinearLayout>

其效果如图:

定义底部的输入布局

frag_chat_bottom_layout.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="#FFEEEEEE" >
       <Button
             android:id="@+id/multi_function_btn"
             android:layout_width="40dp"
             android:layout_height="40dp"
             android:layout_marginLeft="5dip"
             android:background="@drawable/plus_btn"
             android:text=" " />

        <EditText
            android:id="@+id/chat_content"
            android:textColor="#000000"
            android:layout_width="wrap_content"
            android:layout_height="45dip"
            android:background="@anim/edit_text"
            android:layout_weight="1.0"
            android:hint="请输入内容"
            android:inputType="textWebEditText"
            android:text="" />

        <Button
            android:id="@+id/chat_sendbtn"
            android:layout_marginLeft="5dip"
            android:background="@drawable/button"
            android:layout_width="wrap_content"
            android:layout_height="45dip"
            android:text=" 发送 " />

</LinearLayout>

其效果如图所示

至此,我们的布局文件算是完成了。接下来,我们需要定义三个Fragment来关联这三个碎片布局

1,抬头

FragChatTitle.java

package com.sanliao.eim.activity.im;

import com.sanliao.eim.R;
import com.sanliao.eim.manager.ContacterManager;
import com.sanliao.eim.manager.XmppConnectionManager;
import com.sanliao.eim.model.User;
import com.sanliao.eim.util.StringUtil;

import android.app.Activity;
import android.app.Fragment;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;

public class FragChatTitle extends Fragment {

	private final static String TAG="FragChatTitle";
	NewChatActivity activity=null;
	private ImageView titleBack;//返回按钮
	private TextView tvChatTitle;//对话用户名
	private ImageButton userInfo;//用户信息按钮
	private User user;// 聊天人
	private String to_name;

	@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Log.d(TAG, "onCreateView");
        return inflater.inflate(R.layout.frag_chat_title_layout, container, false);
    }  

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        Log.d(TAG, "onAttach");
    }  

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate");
    }  

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        Log.d(TAG, "onActivityCreated");
        activity=(NewChatActivity)getActivity();//获得所在activity,并转为newchatactivity
        //返回按钮
    	titleBack = (ImageView) getActivity().findViewById(R.id.title_back);
		titleBack.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				getActivity().finish();
			}
		});
		tvChatTitle = (TextView) getActivity().findViewById(R.id.to_chat_name);
		user = ContacterManager.getByUserJid(activity.getTo(), XmppConnectionManager
				.getInstance().getConnection());
		if (null == user) {
			to_name = StringUtil.getUserNameByJid(activity.getTo());
		} else {
			to_name = user.getName() == null ? user.getJID() : user.getName();

		}
		tvChatTitle.setText(to_name);//将用户名设置到title
		//用户信息
		userInfo = (ImageButton)activity. findViewById(R.id.user_info);
		userInfo.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				Intent intent = new Intent();
				intent.setClass(activity, FriendInfoActivity.class);
				startActivity(intent);
			}
		});
    }  

    @Override
    public void onStart() {
        super.onStart();
        Log.d(TAG, "onStart");
    }  

    @Override
    public void onResume() {
        super.onResume();
        Log.d(TAG, "onResume");
    }  

    @Override
    public void onPause() {
        super.onPause();
        Log.d(TAG, "onPause");
    }  

    @Override
    public void onStop() {
        super.onStop();
        Log.d(TAG, "onStop");
    }  

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        Log.d(TAG, "onDestroyView");
    }  

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy");
    }  

    @Override
    public void onDetach() {
        super.onDetach();
        Log.d(TAG, "onDetach");
    }  

}

定义聊天记录的Fragment

FragChatHistory.java

package com.sanliao.eim.activity.im;

import java.util.List;

import com.sanliao.eim.R;

import com.sanliao.eim.manager.MessageManager;
import com.sanliao.eim.model.IMMessage;
import com.sanliao.eim.model.User;
import com.sanliao.eim.util.StringUtil;

import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

public class FragChatHistory extends Fragment {

	private final static String TAG="FragChatHistory";
	private MessageListAdapter adapter = null;
	private ListView listView;
	private int recordCount;
	private View listHead;
	private Button listHeadButton;
	private User user;// 聊天人

	private   NewChatActivity  activity=null;

	@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Log.d(TAG, "onCreateView");
        return inflater.inflate(R.layout.frag_history_list_layout, container, false);
    }  

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        Log.d(TAG, "onAttach");
    }  

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate");
    }  

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        Log.d(TAG, "onActivityCreated");
        activity=(NewChatActivity) getActivity();

		listView = (ListView) activity.findViewById(R.id.chat_list);
		listView.setCacheColorHint(0);
		adapter = new MessageListAdapter(activity, activity.getMessages(),
				listView);

		// 头

		LayoutInflater mynflater = LayoutInflater.from(activity);
		listHead = mynflater.inflate(R.layout.chatlistheader, null);
		listHeadButton = (Button) listHead.findViewById(R.id.buttonChatHistory);
		listHeadButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				Intent in = new Intent(activity, ChatHistoryActivity.class);
				in.putExtra("to", activity.getTo());
				startActivity(in);
			}
		});
		listView.addHeaderView(listHead);
		listView.setAdapter(adapter);

    }  

    @Override
    public void onStart() {
        super.onStart();
        Log.d(TAG, "onStart");
    }  

    @Override
    public void onResume() {
        super.onResume();
        Log.d(TAG, "onResume");  

    	recordCount = MessageManager.getInstance((NewChatActivity)getActivity())
				.getChatCountWithSb(((NewChatActivity)getActivity()).getTo());
		if (recordCount <= 0) {
			listHead.setVisibility(View.GONE);
		} else {
			listHead.setVisibility(View.VISIBLE);
		}
		adapter.refreshList(((NewChatActivity)getActivity()).getMessages());
    }  

    @Override
    public void onPause() {
        super.onPause();
        Log.d(TAG, "onPause");
    }  

    @Override
    public void onStop() {
        super.onStop();
        Log.d(TAG, "onStop");
    }  

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        Log.d(TAG, "onDestroyView");
    }  

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy");
    }  

    @Override
    public void onDetach() {
        super.onDetach();
        Log.d(TAG, "onDetach");
    }  

	public MessageListAdapter  getAdapter()
	{
	 	return adapter ;
	}
    //////////////////////////////////////////////////////////////////
    public class MessageListAdapter extends BaseAdapter {

		private List<IMMessage> items;
		private Context context;
		private ListView adapterList;
		private LayoutInflater inflater;

		public MessageListAdapter(Context context, List<IMMessage> items,
				ListView adapterList) {
			this.context = context;
			this.items = items;
			this.adapterList = adapterList;
		}

		public void refreshList(List<IMMessage> items) {
			this.items = items;
			this.notifyDataSetChanged();
			adapterList.setSelection(items.size() - 1);
		}

		@Override
		public int getCount() {
			return items == null ? 0 : items.size();
		}

		@Override
		public Object getItem(int position) {
			return items.get(position);
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			inflater = (LayoutInflater) context
					.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			IMMessage message = items.get(position);
			if (message.getMsgType() == 0) {
				convertView = this.inflater.inflate(
						R.layout.formclient_chat_in, null);
			} else {
				convertView = this.inflater.inflate(
						R.layout.formclient_chat_out, null);
			}
			TextView useridView = (TextView) convertView
					.findViewById(R.id.formclient_row_userid);
			TextView dateView = (TextView) convertView
					.findViewById(R.id.formclient_row_date);
			TextView msgView = (TextView) convertView
					.findViewById(R.id.formclient_row_msg);
			if (message.getMsgType() == 0) {
				if (null == user) {
					useridView.setText(StringUtil.getUserNameByJid(((NewChatActivity)getActivity()).to));
				} else {
					useridView.setText(user.getName());
				}

			} else {
				useridView.setText("我");
			}
			dateView.setText(message.getTime());
			msgView.setText(message.getContent());
			return convertView;
		}

	}

}

定义底部Fragment

FragChatBottom.java

package com.sanliao.eim.activity.im;

import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.sanliao.eim.R;

public class FragChatBottom extends Fragment {
	private final static String TAG="FragChatBottom";
	private EditText messageInput = null;
	private Button messageSendBtn = null;

	@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Log.d(TAG, "onCreateView");
        return inflater.inflate(R.layout.frag_chat_bottom_layout, container, false);
    }  

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        Log.d(TAG, "onAttach");
    }  

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate");
    }  

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        Log.d(TAG, "onActivityCreated");
        messageInput = (EditText) getActivity().findViewById(R.id.chat_content);
		messageSendBtn = (Button) getActivity().findViewById(R.id.chat_sendbtn);
		messageSendBtn.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				String message = messageInput.getText().toString();
				if ("".equals(message)) {
					Toast.makeText(getActivity(), "不能为空",
							Toast.LENGTH_SHORT).show();
				} else {

					try {
						((NewChatActivity)getActivity()).sendMessage(message);
						messageInput.setText("");
					} catch (Exception e) {
						((NewChatActivity)getActivity()).showToast("信息发送失败");
						messageInput.setText(message);
					}
					((NewChatActivity)getActivity()).closeInput();
				}
			}
		});
    }  

    @Override
    public void onStart() {
        super.onStart();
        Log.d(TAG, "onStart");
    }  

    @Override
    public void onResume() {
        super.onResume();
        Log.d(TAG, "onResume");
    }  

    @Override
    public void onPause() {
        super.onPause();
        Log.d(TAG, "onPause");
    }  

    @Override
    public void onStop() {
        super.onStop();
        Log.d(TAG, "onStop");
    }  

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        Log.d(TAG, "onDestroyView");
    }  

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy");
    }  

    @Override
    public void onDetach() {
        super.onDetach();
        Log.d(TAG, "onDetach");
    }  

}

最后,我们需要在NewChatActivity中将这三个Fragment组装起来。

NewChat.java

package com.sanliao.eim.activity.im;

import java.util.List;

import org.jivesoftware.smackx.InitStaticCode;

import com.sanliao.eim.R;
import com.sanliao.eim.model.IMMessage;

import android.app.Activity;
import android.os.Bundle;

public class NewChatActivity extends  AChatActivity{
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.new_chat_layout);

		init();

	}

	public void init()
	{
		FragChatTitle fragChatTitle = new FragChatTitle();
        getFragmentManager().beginTransaction().replace(R.id.chat_title_layout,fragChatTitle).commit();
        FragChatHistory fragChatHistory=new FragChatHistory();
       getFragmentManager().beginTransaction().replace(R.id.chat_history_layout,fragChatHistory).commit();
        FragChatBottom fragChatBottom=new FragChatBottom();
        getFragmentManager().beginTransaction().replace(R.id.chat_bottom_layout,fragChatBottom).commit();
	}

	@Override
	protected void receiveNewMessage(IMMessage message) {
		// TODO Auto-generated method stub

	}

	@Override
	protected void refreshMessage(List<IMMessage> messages) {
		// TODO Auto-generated method stub
		FragChatHistory fragment = (FragChatHistory ) getFragmentManager().findFragmentById(R.id.chat_history_layout);
		fragment.getAdapter().refreshList(messages);

	}

}

对于这个类,大家看到了它继承AchatActivity,关于这个类图结构,大家最好翻阅一下之前的一篇文章:《三僚智能家居软件设计》

http://blog.csdn.net/minimicall/article/details/38680087

好,跑起来。就会得到如图1所示的效果。好,打完收工。

时间: 2024-11-07 21:42:15

Fragment实践之聊天窗口的相关文章

Fragment实践————简易版新闻应用

项目名称:FragmentBestPratice 碎片的生命周期 Fragment onAttach():当碎片和活动建立关联的时候调用 onCreateView():为碎片创建视图时调用. onActivityCreate:确保与碎片相关联的活动一定已经创建完毕的时候调用. onDestroyView:当与碎片关联的视图被移除的时候调用. onDetach:当碎片和活动解除关联的时候调用. 原文地址:https://www.cnblogs.com/kyun/p/9840304.html

ActionBar Fragment运用最佳实践

ActionBar Fragment运用最佳实践

Android学习路线(二十四)ActionBar Fragment运用最佳实践

通过前面的几篇博客,大家看到了Google是如何解释action bar和fragment以及推荐的用法.俗话说没有demo的博客不是好博客,下面我会介绍一下action bar和fragment在实战中的应用,以及相关demo源码,希望和大家相互交流. 了解过fragment的同学们应该都知道,fragment是android 3.0版本才出现的的,因此如果要在支持android 3.0一下版本的工程中使用fragment的话是需要添加Support Library的.具体如何添加我就不再赘述

Fragment管理最佳实践

现在的app视图中tab+fragment是最常用的一种布局,但是如果使用才是更简洁更有效的呢?下面通过一个demo的分类测试来分析下: add remove replace detach attach hide show这些方法的使用对Fragment生命周期的影响分析: 顺便分析下Fragment所依赖的Activity的生命周期: 测试代码如下: MainActivity的代码如下: package com.testfragmentlifecircle; import android.co

【Android开发实践】android.view.InflateException: Binary XML file line #12: Error inflating class fragment问题解决

一般出现的原因是fragment引入的包错了,应该是import android.app.ListFragment;而不是import android.support.v4.app.ListFragment;

Android Fragment 真正的完全解析(上)

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/37970961 自从Fragment出现,曾经有段时间,感觉大家谈什么都能跟Fragment谈上关系,做什么都要问下Fragment能实现不~~~哈哈,是不是有点过~~~ 本篇博客力求为大家说明Fragment如何产生,什么是Fragment,Fragment生命周期,如何静态和动态的使用Fragment,Fragment回退栈,Fragment事务:以及Fragment的一些特

Android Fragment 真正的完全解析

出处: 自从Fragment出现,曾经有段时间,感觉大家谈什么都能跟Fragment谈上关系,做什么都要问下Fragment能实现不~~~哈哈,是不是有点过~~~ 本篇博客力求为大家说明Fragment如何产生,什么是Fragment,Fragment生命周期,如何静态和动态的使用Fragment,Fragment回退栈,Fragment事务:以及Fragment的一些特殊用途,例如:没有布局的Fragment有何用处?Fragment如何与Activity交互?Fragment如何创建对话框?

Glow Android 优化实践

了解 Glow 的朋友应该知道,我们主营四款 App,分别是Eve.Glow.Nuture和Baby.作为创业公司,我们的四款 App 都处于高速开发中,平均每个 Android App 由两人负责开发,包括 Android 和 Server 开发,在满足 PM 各种需求的同时,我们的 session crash free 率保持不低于 99.8%,其中两款 App 接近 100%. 本文将对 Glow 当前 Android App 中对现有工具的探索及优化进行讲解,希望对读者有所启发. 整体结

【Android自学日记】【转】Android Fragment 真正的完全解析(上)

自从Fragment出现,曾经有段时间,感觉大家谈什么都能跟Fragment谈上关系,做什么都要问下Fragment能实现不~~~哈哈,是不是有点过~~~ 本篇博客力求为大家说明Fragment如何产生,什么是Fragment,Fragment生命周期,如何静态和动态的使用Fragment,Fragment回退栈,Fragment事务:以及Fragment的一些特殊用途,例如:没有布局的Fragment有何用处?Fragment如何与Activity交互?Fragment如何创建对话框?Frag