前几天刚学了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); } }
http://blog.csdn.net/minimicall/article/details/38680087
好,跑起来。就会得到如图1所示的效果。好,打完收工。