android imitating wechat demo -- implementation of wechat message interface (mobile terminal)

Previous articles

android imitation wechat demo -- implementation of wechat startup page

android imitation wechat demo -- implementation of registration function (mobile terminal)

android imitation wechat demo -- implementation of registration function (server)

android imitation wechat demo -- Realization of login function (mobile terminal)

android imitation wechat demo -- implementation of login function (server)

android imitating wechat demo -- implementation of wechat main interface

Implementation of wechat message page on mobile terminal

In the previous article, the main interface implementation said that there are fragments in the middle of the four wechat pages, and the layout of the four fragments has not been realized, so this article mainly realizes the implementation of wechat message interface (the first fragment)

The wechat message page can slide up and down. Each list can display up to five data, and you can also click the list

To realize the appeal function, you only need to use ListView in the fragment layout, and then assign an Item layout to the ListView

Modify the fragment layout of wechat message page
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>

The above code defines a split line

Each list of wechat message page has a dividing line, and the dividing line provided by the system is full of screen width, so you should define a dividing line yourself

Custom split line 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>

Create item layout corresponding to ListView in wechat message page fragment
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>

Modify wechat message page fragment java code

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 {
    //Wechat is used to find wechat message list
    private String number;
    // Declaration component
    private ListView listView;
    // Create a collection to store some information from the server to display the wechat message list
    private List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
    //A custom handler message mechanism
    private MyHander myhander = new MyHander();
    /*Parametric construction method, the parameter is micro signal*/
    @SuppressLint("ValidFragment")
    WeixinFragment(String number) {
        this.number = number;
    }
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // Open a thread to complete the network request operation
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                httpUrlConnPost(String.valueOf(number));
            }
        });
        thread1.start();
        /*Wait for the network request thread to complete*/
        try {
            thread1.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //Get fragment layout
        View view = inflater.inflate(R.layout.weixin_fragment, container, false);
        //Initialize component
        listView = view.findViewById(R.id.listView);
        //Create a custom adapter to display data on the component
        BaseAdapter adapter = new ImageAdapter(getActivity().getApplicationContext(), list);
        //Set up adapter
        listView.setAdapter(adapter);
        return view;
    }

    // 1. Write a method to send a request
    // Main method of sending request
    public void httpUrlConnPost(String number) {
        HttpURLConnection urlConnection = null;
        URL url;
        try {
            // URL address of the request
            url = new URL(
                    "http://100.2.178.10:8080/AndroidServer_war_exploded/WeixinInformation");
            urlConnection = (HttpURLConnection) url.openConnection();// Open http connection
            urlConnection.setConnectTimeout(3000);// Timeout for connection
            urlConnection.setUseCaches(false);// Do not use cache
            // urlConnection.setFollowRedirects(false); Is a static function that acts on all URLConnection objects.
            urlConnection.setInstanceFollowRedirects(true);// Is a member function, which only works on the current function and sets whether the connection can be redirected
            urlConnection.setReadTimeout(3000);// Response timeout
            urlConnection.setDoInput(true);// Set whether this connection can write data
            urlConnection.setDoOutput(true);// Set whether this connection can output data
            urlConnection.setRequestMethod("POST");// How to set the request
            urlConnection.setRequestProperty("Content-Type",
                    "application/json;charset=UTF-8");// Set the type of message
            urlConnection.connect();// The configuration from the above to now must be completed before connect. In fact, it only establishes a TCP connection with the server
            JSONObject json = new JSONObject();// Create json object
            //json.put("title", URLEncoder.encode(title, "UTF-8"));//  Use urlencoder Encode encodes special and invisible characters
            json.put("number", URLEncoder.encode(number, "UTF-8"));// put data into json object
            String jsonstr = json.toString();// Convert JSON objects into strings according to the encoding format of JSON
            // ------------Character stream write data------------
            OutputStream out = urlConnection.getOutputStream();// The output stream is used to send requests. In fact, http requests are not officially sent out until this function
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out));// The highest efficiency is achieved by creating a character stream object and wrapping it with an efficient buffer stream. It is recommended to use character stream for sending strings and byte stream for other data
            bw.write(jsonstr);// Write json string to buffer
            bw.flush();// It is important to refresh the buffer and send the data
            out.close();
            bw.close();// Close after use
            Log.i("aa", urlConnection.getResponseCode() + "");
            //The following determines whether the access is successful. If the returned status code is 200, the access is successful
            if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {// Get the return code of the server and check whether the connection is successful
                // ------------The character stream reads the data returned by the server------------
                InputStream in = urlConnection.getInputStream();
                BufferedReader br = new BufferedReader(
                        new InputStreamReader(in));
                String str = null;
                StringBuffer buffer = new StringBuffer();
                while ((str = br.readLine()) != null) {// BufferedReader has a unique function to read one row of data at a time
                    System.out.println("Test:" + 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("website:" + pic[i]);
                    map.put("title", title[i]);
                    System.out.println("website:" + title[i]);
                    map.put("content", content[i]);
                    map.put("time", time[i]);
                    map.put("code", pic2[i]);
                    list.add(map);//Put the map into the list collection
                }
                boolean result = rjson.getBoolean("json");// Get the data with the key value of "json" from the rjson object. Here, the server returns a boolean type of data
                System.out.println("json:===" + result);
                //If the server returns true, it indicates that the wechat page Jump is successful and the wechat page Jump fails
                if (result) {// Judge whether the result is correct
                    //In Android, http requests must be put into the thread to make requests, but the UI cannot be modified directly in the thread. The UI can only be operated through the handler mechanism
                    myhander.sendEmptyMessage(1);
                    Log.i("User:", "Successfully jump to wechat page");
                } else {
                    myhander.sendEmptyMessage(2);
                    System.out.println("222222222222222");
                    Log.i("User:", "Failed to jump to wechat page");
                }
            } else {
                myhander.sendEmptyMessage(2);
            }
        } catch (Exception e) {
            e.printStackTrace();

            Log.i("aa", e.toString());
            System.out.println("11111111111111111");
            myhander.sendEmptyMessage(2);
        } finally {
            urlConnection.disconnect();// Close the TCP connection and free up resources after use
        }
    }

    // In Android, you can't directly modify the UI in the thread. You can only complete the UI operation with the help of the Handler mechanism
    class MyHander extends Handler {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            //Judge what the content of the handler is. If it is 1, it means that the jump to wechat page is successful; if it is 2, it means that the jump to wechat page fails
            switch (msg.what) {
                case 1:
                    Log.i("aa", msg.what + "");
                    break;
                case 2:
                    Log.i("aa", msg.what + "");
            }

        }
    }
}

The specific content of the above code is not described, and the code has comments. Let's mainly talk about the adapter set for ListView above. Its customized adapter inherits the system's own adapter BaseAdapter, rewrites the corresponding method, and displays the data on the corresponding component of the item layout corresponding to LlistView. As for why to customize, because each list on the wechat information page has at least two picture data, To load the picture into the component, you need to use the tool class (which will be given later)

Above fragment Java code has customized an adapter. Now create it. Before creating it, you can create a package to store the adapter separately for easy management;

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 {
    // A collection of data to display
    private List<Map<String, Object>> data;
    // Accept context
    private Context context;
    // Declare an inner class object
    private ViewHolder viewHolder;

    public ImageAdapter(Context context, List<Map<String, Object>> data) {
        this.context = context;
        this.data = data;
    }

    // Total number of returned
    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return data.size();
    }

    // Returns the data corresponding to each entry
    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return data.get(position);
    }

    // Returned id
    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    // Returns the control object corresponding to this entry
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // Determine whether the current entry is 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();
        }
        // Gets the map object in the List collection
        Map<String, Object> map = data.get(position);
        // Get the url path of the picture
        String pic = map.get("pic").toString();
        // Here, the setImage method of the image loading tool class is called to display the image directly on the control
        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);
        // Get the url path of the picture
        String code = map.get("code").toString();
        // Here, the setImage method of the image loading tool class is called to display the image directly on the control
        GetImageByUrl getImageByUrl2 = new GetImageByUrl();
        getImageByUrl2.setImage(viewHolder.code, code);

        return convertView;
    }

    /**
     * The inner class records all attributes in a single entry
     *
     *
     *
     */
    class ViewHolder {
        public ImageView img1;
        public TextView title;
        public TextView content;
        public TextView time;
        public ImageView code;
    }
}

The image loading tool class used above will be given later

Create a picture loading tool class getimagebyurl. In toolkit tools 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;

/**
 * Get the picture according to the picture url path
 *
 *
 *
 */
public class GetImageByUrl {

    private PicHandler pic_hdl;
    private ImageView imgView;
    private String url;
    
    /**
     * Get the picture through the picture url path and display it on the corresponding control
     *
     *
     *
     */
    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;
    }
}

At this point, the mobile end of the wechat message page is completed. Because the server function has not been realized, the wechat message page is blank during the test, because the Item layout corresponding to ListView has no data by default, and the data is obtained from the server. The next article will improve the function of the server

Added by sander_ESP on Sat, 29 Jan 2022 19:55:46 +0200