android 仿微信demo————微信启动界面实现

android 仿微信demo————注册功能实现(移动端)

android 仿微信demo————注册功能实现(服务端)

android 仿微信demo————登录功能实现(移动端)

android 仿微信demo————登录功能实现(服务端)

android 仿微信demo————微信主界面实现

android 仿微信demo————微信消息界面实现(移动端)

android 仿微信demo————微信消息界面实现(服务端)

android 仿微信demo————微信通讯录界面功能实现(移动端,服务端)

android 仿微信demo————微信发现界面实现

android 仿微信demo————微信顶部操作栏界面实现

android 仿微信demo————微信顶部操作栏搜索按钮实现(查询通讯录好友功能)

android 仿微信demo————微信顶部操作栏加号按钮实现(弹出子菜单)

文章目录

  • 移动端微信消息页实现

移动端微信消息页实现

在上一篇中主界面实现说过微信四个页面中间都是是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布局默认是没有数据的,数据是从服务器获取的,下一篇会完善服务端功能

更多相关文章

  1. Android跨进程通信IPC之4——AndroidIPC基础1
  2. Android实现头像上传
  3. Android数据加密之Des加密
  4. Android真响应式架构——MvRx
  5. Android(安卓)核心分析(13) -----Android(安卓)GWES之Android窗
  6. Android进阶——Android消息机制之Looper、Handler、MessageQuee
  7. Android圆型头像实现
  8. 它山之石
  9. Android(安卓)之 ProgressBar用法介绍

随机推荐

  1. 对AndroidManifest.xml的一点理解
  2. Android获取手机经纬度
  3. Ubuntu编译Android使用的FFmpeg
  4. android的动画
  5. Visual Studio 跨平台開發實戰(4) - Xama
  6. Android入门教程(四)之-------->Android
  7. Android NDK 简介
  8. android入门教程(十六)之-- 使用Intent传
  9. webView中js调用android方法一调用程序就
  10. 在定制android设备时,刷机后不全屏显示或