目录
移动端微信消息页实现
在上一篇中主界面实现说过微信四个页面中间都是是fragment的,并且四个fragment的布局都还没实现,所以这一篇主要实现微信消息界面的实现(第一个fragment)
微信消息页是可以上下滑动,每一个列表最多都有可显示五个数据,还可以点击列表

要实现上诉功能只需要在fragment布局中使用ListView,然后给ListView指定一个Item布局即可
修改微信消息界面fragment布局
weixin_fragment.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:id="@+id/listView" android:layout_width="match_parent" android:layout_height="wrap_content" android:divider="@drawable/main_list_divider_line" android:dividerHeight="1.5px" android:layout_marginBottom="50dp"> </ListView> </LinearLayout>
上述代码自定义了一个分割线
微信消息页每一个列表都有分割线,而系统自带的分割线是充满屏幕宽度的,所以要自己定义一个分割线
自定义分割线main_list_divider_line.xml
main_list_divider_line.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:left="80dp"
android:right="0dp">
<shape android:shape="rectangle" >
<solid android:color="#33000000" />
</shape>
</item>
</layer-list>
创建微信消息界面fragment中ListView对应的item布局
weixin_item.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="80dp"
android:layout_marginTop="300dp"
android:padding="10dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/img1"
android:layout_width="20dp"
android:layout_height="wrap_content"
android:layout_weight="0.5"/>
<LinearLayout
android:orientation="vertical"
android:layout_marginLeft="23dp"
android:layout_width="8dp"
android:layout_height="match_parent"
android:layout_weight="4">
<TextView
android:id="@+id/title"
android:textColor="#000000"
android:textSize="18dp"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="2.5"/>
<TextView
android:id="@+id/content"
android:textColor="#A8A8A8"
android:gravity="center_vertical"
android:singleLine="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1.5"/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingRight="-50dp"
android:layout_weight="1"
android:gravity="right"
android:orientation="vertical">
<TextView
android:id="@+id/time"
android:textColor="#A8A8A8"
android:textSize="15dp"
android:layout_gravity="right"
android:layout_marginRight="1dp"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.5"/>
<ImageView
android:id="@+id/code"
android:background="@color/white"
android:layout_gravity="right"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.5"/>
</LinearLayout>
</LinearLayout>
修改微信消息界面fragment.java代码
package com.example.wxchatdemo; import android.annotation.SuppressLint; import android.app.Fragment; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.annotation.Nullable; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ListView; import com.example.wxchatdemo.adapter.ImageAdapter; import org.json.JSONObject; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @SuppressLint("ValidFragment") public class WeixinFragment extends Fragment { //微信号,用于查找微信消息列表 private String number; // 声明组件 private ListView listView; // 创建集合用于存储服务器发来的显示微信消息列表的一些信息 private List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); //自定义的一个Hander消息机制 private MyHander myhander = new MyHander(); /*有参构造方法,参数为微信号*/ @SuppressLint("ValidFragment") WeixinFragment(String number) { this.number = number; } @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // 开一个线程完成网络请求操作 Thread thread1 = new Thread(new Runnable() { @Override public void run() { httpUrlConnPost(String.valueOf(number)); } }); thread1.start(); /*等待网络请求线程完成*/ try { thread1.join(); } catch (InterruptedException e) { e.printStackTrace(); } //获取fragment布局 View view = inflater.inflate(R.layout.weixin_fragment, container, false); //初始化组件 listView = view.findViewById(R.id.listView); //创建自定义的适配器,用于把数据显示在组件上 BaseAdapter adapter = new ImageAdapter(getActivity().getApplicationContext(), list); //设置适配器 listView.setAdapter(adapter); return view; } // 1.编写一个发送请求的方法 // 发送请求的主要方法 public void httpUrlConnPost(String number) { HttpURLConnection urlConnection = null; URL url; try { // 请求的URL地地址 url = new URL( "http://100.2.178.10:8080/AndroidServer_war_exploded/WeixinInformation"); urlConnection = (HttpURLConnection) url.openConnection();// 打开http连接 urlConnection.setConnectTimeout(3000);// 连接的超时时间 urlConnection.setUseCaches(false);// 不使用缓存 // urlConnection.setFollowRedirects(false);是static函数,作用于所有的URLConnection对象。 urlConnection.setInstanceFollowRedirects(true);// 是成员函数,仅作用于当前函数,设置这个连接是否可以被重定向 urlConnection.setReadTimeout(3000);// 响应的超时时间 urlConnection.setDoInput(true);// 设置这个连接是否可以写入数据 urlConnection.setDoOutput(true);// 设置这个连接是否可以输出数据 urlConnection.setRequestMethod("POST");// 设置请求的方式 urlConnection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");// 设置消息的类型 urlConnection.connect();// 连接,从上述至此的配置必须要在connect之前完成,实际上它只是建立了一个与服务器的TCP连接 JSONObject json = new JSONObject();// 创建json对象 //json.put("title", URLEncoder.encode(title, "UTF-8"));// 使用URLEncoder.encode对特殊和不可见字符进行编码 json.put("number", URLEncoder.encode(number, "UTF-8"));// 把数据put进json对象中 String jsonstr = json.toString();// 把JSON对象按JSON的编码格式转换为字符串 // ------------字符流写入数据------------ OutputStream out = urlConnection.getOutputStream();// 输出流,用来发送请求,http请求实际上直到这个函数里面才正式发送出去 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out));// 创建字符流对象并用高效缓冲流包装它,便获得最高的效率,发送的是字符串推荐用字符流,其它数据就用字节流 bw.write(jsonstr);// 把json字符串写入缓冲区中 bw.flush();// 刷新缓冲区,把数据发送出去,这步很重要 out.close(); bw.close();// 使用完关闭 Log.i("aa", urlConnection.getResponseCode() + ""); //以下判斷是否訪問成功,如果返回的状态码是200则说明访问成功 if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {// 得到服务端的返回码是否连接成功 // ------------字符流读取服务端返回的数据------------ InputStream in = urlConnection.getInputStream(); BufferedReader br = new BufferedReader( new InputStreamReader(in)); String str = null; StringBuffer buffer = new StringBuffer(); while ((str = br.readLine()) != null) {// BufferedReader特有功能,一次读取一行数据 System.out.println("测试:" + str); buffer.append(str); } in.close(); br.close(); JSONObject rjson = new JSONObject(buffer.toString()); String str1 = rjson.getJSONObject("json").get("titleimg").toString(); String[] pic = str1.split("\r\n"); String str2 = rjson.getJSONObject("json").get("title").toString(); String[] title = str2.split("\r\n"); String str3 = rjson.getJSONObject("json").get("content").toString(); String[] content = str3.split("\r\n"); String str4 = rjson.getJSONObject("json").get("time").toString(); String[] time = str4.split("\r\n"); String str5 = rjson.getJSONObject("json").get("showcode").toString(); String[] pic2 = str5.split("\r\n"); for (int i = 0; i < pic.length; i++) { Map<String, Object> map = new HashMap<String, Object>(); map.put("pic", pic[i]); System.out.println("网址:" + pic[i]); map.put("title", title[i]); System.out.println("网址:" + title[i]); map.put("content", content[i]); map.put("time", time[i]); map.put("code", pic2[i]); list.add(map);//将map放到list集合中 } boolean result = rjson.getBoolean("json");// 从rjson对象中得到key值为"json"的数据,这里服务端返回的是一个boolean类型的数据 System.out.println("json:===" + result); //如果服务器端返回的是true,则说明跳转微信页成功,跳转微信页失败 if (result) {// 判断结果是否正确 //在Android中http请求,必须放到线程中去作请求,但是在线程中不可以直接修改UI,只能通过hander机制来完成对UI的操作 myhander.sendEmptyMessage(1); Log.i("用户:", "跳转微信页成功"); } else { myhander.sendEmptyMessage(2); System.out.println("222222222222222"); Log.i("用户:", "跳转微信页失败"); } } else { myhander.sendEmptyMessage(2); } } catch (Exception e) { e.printStackTrace(); Log.i("aa", e.toString()); System.out.println("11111111111111111"); myhander.sendEmptyMessage(2); } finally { urlConnection.disconnect();// 使用完关闭TCP连接,释放资源 } } // 在Android中不可以在线程中直接修改UI,只能借助Handler机制来完成对UI的操作 class MyHander extends Handler { @Override public void handleMessage(Message msg) { super.handleMessage(msg); //判断hander的内容是什么,如果是1则说明跳转微信页成功,如果是2说明跳转微信页失败 switch (msg.what) { case 1: Log.i("aa", msg.what + ""); break; case 2: Log.i("aa", msg.what + ""); } } } }
上述代码具体的内容就不阐述了,代码都有注释。主要说一下上面给ListView设置适配器,它是自定义的适配器,通过继承系统自带适配器BaseAdapter,重写相应方法,把数据显示在LlistView对应的item布局相应组件上,至于为什么要自定义,因为微信消息页每一个列表都有至少两个图片数据,而要把图片加载到组件上需要用到工具类(后面会给出)
上面fragment.java代码自定义了一个适配器,现在就来创建它,创建之前,可以先创建包单独存放适配器,方便管理;


ImageAdapter.java
package com.example.wxchatdemo.adapter;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.wxchatdemo.tools.GetImageByUrl;
import com.example.wxchatdemo.R;
import java.util.List;
import java.util.Map;
public class ImageAdapter extends BaseAdapter {
// 要显示的数据的集合
private List<Map<String, Object>> data;
// 接受上下文
private Context context;
// 声明内部类对象
private ViewHolder viewHolder;
public ImageAdapter(Context context, List<Map<String, Object>> data) {
this.context = context;
this.data = data;
}
// 返回的总个数
@Override
public int getCount() {
// TODO Auto-generated method stub
return data.size();
}
// 返回每个条目对应的数据
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return data.get(position);
}
// 返回的id
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
// 返回这个条目对应的控件对象
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// 判断当前条目是否为null
if (convertView == null) {
viewHolder = new ViewHolder();
convertView = View.inflate(context, R.layout.weixin_item, null);
viewHolder.img1 = (ImageView) convertView
.findViewById(R.id.img1);
viewHolder.title = (TextView) convertView
.findViewById(R.id.title);
viewHolder.content = (TextView) convertView
.findViewById(R.id.content);
viewHolder.time = (TextView) convertView
.findViewById(R.id.time);
viewHolder.code = (ImageView) convertView
.findViewById(R.id.code);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
// 获取List集合中的map对象
Map<String, Object> map = data.get(position);
// 获取图片的url路径
String pic = map.get("pic").toString();
// 这里调用了图片加载工具类的setImage方法将图片直接显示到控件上
GetImageByUrl getImageByUrl = new GetImageByUrl();
getImageByUrl.setImage(viewHolder.img1, pic);
String title = map.get("title").toString();
viewHolder.title.setText(title);
String content = map.get("content").toString();
viewHolder.content.setText(content);
String time = map.get("time").toString();
viewHolder.time.setText(time);
// 获取图片的url路径
String code = map.get("code").toString();
// 这里调用了图片加载工具类的setImage方法将图片直接显示到控件上
GetImageByUrl getImageByUrl2 = new GetImageByUrl();
getImageByUrl2.setImage(viewHolder.code, code);
return convertView;
}
/**
* 内部类 记录单个条目中所有属性
*
*
*
*/
class ViewHolder {
public ImageView img1;
public TextView title;
public TextView content;
public TextView time;
public ImageView code;
}
}
上面用到图片加载工具类,后面会给出
在工具包tools中创建图片加载工具类GetImageByUrl.java
GetImageByUrl.java
package com.example.wxchatdemo.tools;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Message;
import android.widget.ImageView;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* 根据图片url路径获取图片
*
*
*
*/
public class GetImageByUrl {
private PicHandler pic_hdl;
private ImageView imgView;
private String url;
/**
* 通过图片url路径获取图片并显示到对应控件上
*
*
*
*/
public void setImage(ImageView imgView, String url) {
this.url = url;
this.imgView = imgView;
pic_hdl = new PicHandler();
Thread t = new LoadPicThread();
t.start();
}
class LoadPicThread extends Thread {
@Override
public void run() {
Bitmap img = getUrlImage(url);
System.out.println(img + "---");
Message msg = pic_hdl.obtainMessage();
msg.what = 0;
msg.obj = img;
pic_hdl.sendMessage(msg);
}
}
class PicHandler extends Handler {
@Override
public void handleMessage(Message msg) {
Bitmap myimg = (Bitmap) msg.obj;
imgView.setImageBitmap(myimg);
}
}
public Bitmap getUrlImage(String url) {
Bitmap img = null;
try {
URL picurl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) picurl
.openConnection();
conn.setConnectTimeout(6000);
conn.setDoInput(true);
conn.setUseCaches(false);
conn.connect();
InputStream is = conn.getInputStream();
img = BitmapFactory.decodeStream(is);
is.close();
} catch (Exception e) {
e.printStackTrace();
}
return img;
}
}
总结
到此微信消息页移动端就完成了,由于服务端功能还没实现,所以测试时微信消息页显示的是空白的,因为ListView对应Item布局默认是没有数据的,数据是从服务器获取的,下一篇会完善服务端功能,也希望大家可以关注华域联盟其他内容!

评论(0)