1.引言
ListView多布局Item的实现,例如QQ聊天界面

1.1 要点讲解
重写getItemViewType()方法对应View是哪个类别,以及getViewTypeCount()方法iew返回 总共多少个类别!然后再getView那里调用getItemViewType获得对应类别,再加载对应的View!
2. 代码实现
2.1 列表
一个简单基础的ListView,可以添加到任意想要添加的位置
1 2 3 4 5 6 7 8 9 10 11
| <?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">
<ListView android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
|
2.2 区分左右的两个item
靠左对齐
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| <?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:orientation="horizontal"
>
<de.hdodenhof.circleimageview.CircleImageView android:id="@+id/qqtouxiang" android:layout_width="40dp" android:layout_height="40dp" android:layout_marginStart="15dp" android:layout_marginTop="10dp" android:src="@drawable/touxiang" /> <TextView android:id="@+id/qqMessage" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="nihao" android:textSize="17dp" android:layout_marginStart="5dp" android:layout_marginTop="10dp" android:textColor="@color/black" android:background="@drawable/messagebackground" android:padding="8dp" /> </LinearLayout>
|
靠右对齐
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| <?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:orientation="horizontal" android:gravity="end"
>
<TextView android:id="@+id/qqMessage1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:background="@drawable/messagebackground" android:padding="8dp" android:layout_marginBottom="10dp" android:text="nihao" android:textColor="@color/black" android:textSize="17dp" android:gravity="right" /> <de.hdodenhof.circleimageview.CircleImageView android:id="@+id/qqtouxiang1" android:layout_width="40dp" android:layout_height="40dp" android:layout_marginStart="5dp" android:layout_marginTop="10dp" android:layout_marginEnd="15dp" android:src="@drawable/touxiang" /> </LinearLayout>
|
2.3 靠左对齐的对象方法
LeftType:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| package com.example.pageview.Intomessage;
public class LeftType { private int aIcon; private String aName;
public LeftType(int aIcon, String aName) { this.aIcon = aIcon; this.aName = aName; }
public int getaIcon() { return aIcon; }
public String getaName() { return aName; } }
|
RightType:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| package com.example.pageview.Intomessage;
public class RightType { int image; String bName;
public RightType(int image, String bName) { this.image = image; this.bName = bName; }
public int getImage() { return image; } public String getbName() { return bName; } }
|
2.4 类型选择器
这是一个自定义类型的适配器TypeAdapter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
| package com.example.pageview.Intomessage;
import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView;
import com.example.pageview.R;
import java.util.ArrayList;
public class TypeAdapter extends BaseAdapter {
private static final int TYPE_RIGHT = 0; private static final int TYPE_LEFT = 1;
private Context mContext; private ArrayList<Object> mData;
public TypeAdapter(Context context, ArrayList<Object> data) { this.mContext = context; this.mData = data; }
@Override public int getCount() { return mData.size(); }
@Override public Object getItem(int position) { return mData.get(position); }
@Override public long getItemId(int position) { return position; }
@Override public int getItemViewType(int position) { if (mData.get(position) instanceof LeftType) { return TYPE_LEFT; } else if (mData.get(position) instanceof RightType) { return TYPE_RIGHT; } return super.getItemViewType(position); }
@Override public int getViewTypeCount() { return 2; }
@Override public View getView(int position, View convertView, ViewGroup parent) { int type = getItemViewType(position); ViewHolder1 holder1 = null; ViewHolder2 holder2 = null;
if (convertView == null) { switch (type) { case TYPE_LEFT: holder1 = new ViewHolder1(); convertView = LayoutInflater.from(mContext).inflate(R.layout.type1, parent, false); holder1.imgIcon = convertView.findViewById(R.id.qqtouxiang); holder1.txtAname = convertView.findViewById(R.id.qqMessage); convertView.setTag(holder1); break; case TYPE_RIGHT: holder2 = new ViewHolder2(); convertView = LayoutInflater.from(mContext).inflate(R.layout.type2, parent, false); holder2.imgIcon = convertView.findViewById(R.id.qqtouxiang1); holder2.txtBauthor = convertView.findViewById(R.id.qqMessage1); convertView.setTag(holder2); break; } } else { switch (type) { case TYPE_LEFT: holder1 = (ViewHolder1) convertView.getTag(); break; case TYPE_RIGHT: holder2 = (ViewHolder2) convertView.getTag(); break; } }
Object obj = mData.get(position); switch (type) { case TYPE_LEFT: LeftType leftType = (LeftType) obj; if (leftType != null) { holder1.imgIcon.setImageResource(leftType.getaIcon()); holder1.txtAname.setText(leftType.getaName()); } break; case TYPE_RIGHT: RightType rightType = (RightType) obj; if (rightType != null) { holder2.imgIcon.setImageResource(rightType.getImage()); holder2.txtBauthor.setText(rightType.getbName()); } break; } return convertView; }
private static class ViewHolder1 { ImageView imgIcon; TextView txtAname; }
private static class ViewHolder2 { ImageView imgIcon; TextView txtBauthor; } }
|
2.5 信息回传
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
| package com.example.pageview.Intomessage;
import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; import com.example.pageview.R;
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.util.ArrayList; import java.util.List; import java.util.Map;
public class IntoMessage extends AppCompatActivity { private static final String FILE_NAME = "messages.txt"; private ListView listView; private TypeAdapter myAdapter; private ArrayList<Object> mData; private TextView messageTextView; private TextView inputTextView; private ImageView backButton; private Button sendButton;
private static final int TYPE_RIGHT = 0; private static final int TYPE_LEFT = 1;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_into_message);
initializeViews();
Intent intent = getIntent(); String qqName = intent.getStringExtra("qqName"); int qqPhoto = intent.getIntExtra("qqPhoto", 0); String qqNews = intent.getStringExtra("qqNews");
messageTextView.setText(qqName); mData = new ArrayList<>(); mData.add(new LeftType(qqPhoto, qqNews));
backButton.setOnClickListener(view -> finish());
sendButton.setOnClickListener(view -> sendMessage(qqName));
myAdapter = new TypeAdapter(this, mData); listView.setAdapter(myAdapter); loadMessages(qqName); }
private void initializeViews() { listView = findViewById(R.id.listview); backButton = findViewById(R.id.imageview1); messageTextView = findViewById(R.id.qqName); inputTextView = findViewById(R.id.Textview1); sendButton = findViewById(R.id.buuton1); }
private void sendMessage(String qqName) { String messageContent = inputTextView.getText().toString().trim(); if (!messageContent.isEmpty()) { mData.add(new RightType(R.drawable.mylogo, messageContent)); myAdapter.notifyDataSetChanged(); saveMessages(qqName); inputTextView.setText(""); } }
private void saveMessages(String qqName) { try (FileOutputStream fos = openFileOutput(FILE_NAME, Context.MODE_PRIVATE); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fos))) { for (Object obj : mData) { if (obj instanceof RightType) { RightType rightType = (RightType) obj; writer.write(qqName + "," + rightType.getbName() + "," + rightType.getImage()); writer.newLine(); } } } catch (IOException e) { Log.e("IntoMessage", "保存消息时出错", e); } }
private void loadMessages(String qqName) { try (FileInputStream fis = openFileInput(FILE_NAME); BufferedReader reader = new BufferedReader(new InputStreamReader(fis))) { String line; while ((line = reader.readLine()) != null) { String[] parts = line.split(","); if (parts.length == 3 && parts[0].equals(qqName)) { int image = Integer.parseInt(parts[2]); String bName = parts[1]; mData.add(new RightType(image, bName)); } } myAdapter.notifyDataSetChanged(); } catch (IOException e) { Log.e("IntoMessage", "加载消息时出错", e); } }
}
|
3. 等待优化
- 如何传递一些文件,图片类。
- 数据如何从数据库中清洗得到。