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