Continue with the card design from the previous blog, and we'll continue from WeChat To find some clues, let's start by looking at an interface that is the default public number in WeChat, mainly to publish the latest developments on Tencent News. As we can see, it uses a card layout similar to the one we used in the previous article.So, let's make such an interface today!
The first step, of course, is to create the layout of the layout_item, which is the layout of the list item. The layout code is given here directly. The code is not complicated, but the property settings are cumbersome.
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@drawable/radius_bg"
- android:paddingBottom="10dp"
- android:orientation="vertical">
- <ImageView
- android:id="@+id/News_Pic"
- android:layout_width="wrap_content"
- android:layout_height="100dp"
- android:layout_alignParentLeft="true"
- android:layout_alignParentRight="true"
- android:layout_alignParentTop="true"
- android:layout_marginLeft="10dp"
- android:layout_marginRight="10dp"
- android:layout_marginTop="10dp"
- android:contentDescription="@string/Description"
- android:scaleType="center" />
- <TextView
- android:id="@+id/News_Title"
- android:layout_width="wrap_content"
- android:layout_height="30dp"
- android:layout_alignLeft="@+id/News_Pic"
- android:layout_alignRight="@+id/News_Pic"
- android:layout_below="@+id/News_Pic"
- android:background="#707070"
- android:gravity="left|center"
- android:textColor="#ffffff"
- android:contentDescription="@string/Description"
- android:textIsSelectable="true" />
- <TextView
- android:id="@+id/News_Title1"
- android:layout_width="200dp"
- android:layout_height="45dp"
- android:layout_alignLeft="@+id/News_Title"
- android:layout_alignRight="@+id/News_Title2"
- android:layout_below="@+id/News_Title"
- android:layout_marginTop="10dp"
- android:gravity="center"
- android:textIsSelectable="true" />
- <ImageView
- android:id="@+id/News_Pic1"
- android:layout_width="45dp"
- android:layout_height="45dp"
- android:layout_alignRight="@+id/News_Title"
- android:layout_alignTop="@+id/News_Title1"
- android:contentDescription="@string/Description"
- android:scaleType="center" />
- <TextView
- android:id="@+id/News_Title2"
- android:layout_width="200dp"
- android:layout_height="45dp"
- android:layout_alignParentLeft="true"
- android:layout_below="@+id/News_Title1"
- android:layout_margin="10dp"
- android:layout_toLeftOf="@+id/News_Pic1"
- android:gravity="center"
- android:textIsSelectable="true" />
- <ImageView
- android:id="@+id/News_Pic2"
- android:layout_width="45dp"
- android:layout_height="45dp"
- android:layout_alignTop="@+id/News_Title2"
- android:layout_toRightOf="@+id/News_Title2"
- android:contentDescription="@string/Description"
- android:scaleType="center" />
- <TextView
- android:id="@+id/News_Title3"
- android:layout_width="200dp"
- android:layout_height="45dp"
- android:layout_alignLeft="@+id/News_Title1"
- android:layout_alignRight="@+id/News_Title2"
- android:layout_below="@+id/News_Title2"
- android:gravity="center"
- android:textIsSelectable="true" />
- <ImageView
- android:id="@+id/News_Pic3"
- android:layout_width="45dp"
- android:layout_height="45dp"
- android:layout_alignRight="@+id/News_Pic2"
- android:layout_alignTop="@+id/News_Title3"
- android:layout_toRightOf="@+id/News_Title2"
- android:contentDescription="@string/Description"
- android:scaleType="center" />
- </RelativeLayout>
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/radius_bg" android:paddingBottom="10dp" android:orientation="vertical"> <ImageView android:id="@+id/News_Pic" android:layout_width="wrap_content" android:layout_height="100dp" android:layout_alignParentLeft="true" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:layout_marginTop="10dp" android:contentDescription="@string/Description" android:scaleType="center" /> <TextView android:id="@+id/News_Title" android:layout_width="wrap_content" android:layout_height="30dp" android:layout_alignLeft="@+id/News_Pic" android:layout_alignRight="@+id/News_Pic" android:layout_below="@+id/News_Pic" android:background="#707070" android:gravity="left|center" android:textColor="#ffffff" android:contentDescription="@string/Description" android:textIsSelectable="true" /> <TextView android:id="@+id/News_Title1" android:layout_width="200dp" android:layout_height="45dp" android:layout_alignLeft="@+id/News_Title" android:layout_alignRight="@+id/News_Title2" android:layout_below="@+id/News_Title" android:layout_marginTop="10dp" android:gravity="center" android:textIsSelectable="true" /> <ImageView android:id="@+id/News_Pic1" android:layout_width="45dp" android:layout_height="45dp" android:layout_alignRight="@+id/News_Title" android:layout_alignTop="@+id/News_Title1" android:contentDescription="@string/Description" android:scaleType="center" /> <TextView android:id="@+id/News_Title2" android:layout_width="200dp" android:layout_height="45dp" android:layout_alignParentLeft="true" android:layout_below="@+id/News_Title1" android:layout_margin="10dp" android:layout_toLeftOf="@+id/News_Pic1" android:gravity="center" android:textIsSelectable="true" /> <ImageView android:id="@+id/News_Pic2" android:layout_width="45dp" android:layout_height="45dp" android:layout_alignTop="@+id/News_Title2" android:layout_toRightOf="@+id/News_Title2" android:contentDescription="@string/Description" android:scaleType="center" /> <TextView android:id="@+id/News_Title3" android:layout_width="200dp" android:layout_height="45dp" android:layout_alignLeft="@+id/News_Title1" android:layout_alignRight="@+id/News_Title2" android:layout_below="@+id/News_Title2" android:gravity="center" android:textIsSelectable="true" /> <ImageView android:id="@+id/News_Pic3" android:layout_width="45dp" android:layout_height="45dp" android:layout_alignRight="@+id/News_Pic2" android:layout_alignTop="@+id/News_Title3" android:layout_toRightOf="@+id/News_Title2" android:contentDescription="@string/Description" android:scaleType="center" /> </RelativeLayout>
Step 2, we need to write a rounded radius_bg shape for the card.The code is the same as the previous article:
- <?xml version="1.0" encoding="utf-8"?>
- <shape xmlns:android="http://schemas.android.com/apk/res/android" >
- <solid android:color="#ffffff"/>
- <corners android:radius="10dp"/>
- </shape>
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" > <solid android:color="#ffffff"/> <corners android:radius="10dp"/> </shape>Step 3, Card class, where there are two Card classes, BaseCard is the base class and Card is a class inherited from BaseCard:
- /*
- * Message interface of WeChat public platform
- * @Author: Qin Yuanpei
- *
- */
- package com.Android.WeChatCard;
- public class BaseCard
- {
- private int mDrawable;
- private String mDescription;
- public BaseCard(int Drawable,String Description)
- {
- this.mDrawable=Drawable;
- this.mDescription=Description;
- }
- public int getDrawable()
- {
- return mDrawable;
- }
- public void setDrawable(int mDrawable)
- {
- this.mDrawable = mDrawable;
- }
- public String getDescription()
- {
- return mDescription;
- }
- public void setDescription(String mDescription)
- {
- this.mDescription = mDescription;
- }
- }
/* *Mimic WeChat Public Platform Message Interface * @Author: Qin Yuanpei * */ package com.Android.WeChatCard; public class BaseCard { private int mDrawable; private String mDescription; public BaseCard(int Drawable,String Description) { this.mDrawable=Drawable; this.mDescription=Description; } public int getDrawable() { return mDrawable; } public void setDrawable(int mDrawable) { this.mDrawable = mDrawable; } public String getDescription() { return mDescription; } public void setDescription(String mDescription) { this.mDescription = mDescription; } }
- package com.Android.WeChatCard;
- import java.util.ArrayList;
- import java.util.List;
- public class Card extends BaseCard {
- private List<BaseCard> mSubCards;
- public Card(int Drawable, String Description)
- {
- super(Drawable, Description);
- mSubCards=new ArrayList<BaseCard>();
- }
- public void AppendCard(BaseCard mCard)
- {
- mSubCards.add(mCard);
- }
- public List<BaseCard> getSubCards()
- {
- return mSubCards;
- }
- }
package com.Android.WeChatCard; import java.util.ArrayList; import java.util.List; public class Card extends BaseCard { private List<BaseCard> mSubCards; public Card(int Drawable, String Description) { super(Drawable, Description); mSubCards=new ArrayList<BaseCard>(); } public void AppendCard(BaseCard mCard) { mSubCards.add(mCard); } public List<BaseCard> getSubCards() { return mSubCards; } }
Step 4, let's write a custom adapter class, CardAdapter:
- package com.Android.WeChatCard;
- import java.util.List;
- 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;
- public class CardAdapter extends BaseAdapter {
- private Context mContext;
- private List<Card> mCards;
- public CardAdapter(Context mContext,List<Card> mCards)
- {
- this.mContext=mContext;
- this.mCards=mCards;
- }
- @Override
- public int getCount()
- {
- return mCards.size();
- }
- @Override
- public Object getItem(int Index)
- {
- return mCards.get(Index);
- }
- @Override
- public long getItemId(int Index)
- {
- return Index;
- }
- @Override
- public View getView(int Index, View mView, ViewGroup mParent)
- {
- mView=LayoutInflater.from(mContext).inflate(R.layout.layout_item, null);
- //Headline message
- ImageView News_Pic=(ImageView)mView.findViewById(R.id.News_Pic);
- News_Pic.setImageResource(mCards.get(Index).getDrawable());
- TextView News_Title=(TextView)mView.findViewById(R.id.News_Title);
- News_Title.setText(mCards.get(Index).getDescription());
- //Message One
- ImageView News_Pic1=(ImageView)mView.findViewById(R.id.News_Pic1);
- News_Pic1.setImageResource(mCards.get(Index).getSubCards().get(0).getDrawable());
- TextView News_Title1=(TextView)mView.findViewById(R.id.News_Title1);
- News_Title1.setText(mCards.get(Index).getSubCards().get(0).getDescription());
- //Message 2
- ImageView News_Pic2=(ImageView)mView.findViewById(R.id.News_Pic2);
- News_Pic2.setImageResource(mCards.get(Index).getSubCards().get(1).getDrawable());
- TextView News_Title2=(TextView)mView.findViewById(R.id.News_Title2);
- News_Title2.setText(mCards.get(Index).getSubCards().get(1).getDescription());
- //Message Three
- ImageView News_Pic3=(ImageView)mView.findViewById(R.id.News_Pic3);
- News_Pic3.setImageResource(mCards.get(Index).getSubCards().get(2).getDrawable());
- TextView News_Title3=(TextView)mView.findViewById(R.id.News_Title3);
- News_Title3.setText(mCards.get(Index).getSubCards().get(2).getDescription());
- return mView;
- }
- }
package com.Android.WeChatCard; import java.util.List; 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; public class CardAdapter extends BaseAdapter { private Context mContext; private List<Card> mCards; public CardAdapter(Context mContext,List<Card> mCards) { this.mContext=mContext; this.mCards=mCards; } @Override public int getCount() { return mCards.size(); } @Override public Object getItem(int Index) { return mCards.get(Index); } @Override public long getItemId(int Index) { return Index; } @Override public View getView(int Index, View mView, ViewGroup mParent) { mView=LayoutInflater.from(mContext).inflate(R.layout.layout_item, null); //Headline message ImageView News_Pic=(ImageView)mView.findViewById(R.id.News_Pic); News_Pic.setImageResource(mCards.get(Index).getDrawable()); TextView News_Title=(TextView)mView.findViewById(R.id.News_Title); News_Title.setText(mCards.get(Index).getDescription()); //Message One ImageView News_Pic1=(ImageView)mView.findViewById(R.id.News_Pic1); News_Pic1.setImageResource(mCards.get(Index).getSubCards().get(0).getDrawable()); TextView News_Title1=(TextView)mView.findViewById(R.id.News_Title1); News_Title1.setText(mCards.get(Index).getSubCards().get(0).getDescription()); //Message 2 ImageView News_Pic2=(ImageView)mView.findViewById(R.id.News_Pic2); News_Pic2.setImageResource(mCards.get(Index).getSubCards().get(1).getDrawable()); TextView News_Title2=(TextView)mView.findViewById(R.id.News_Title2); News_Title2.setText(mCards.get(Index).getSubCards().get(1).getDescription()); //Message 3 ImageView News_Pic3=(ImageView)mView.findViewById(R.id.News_Pic3); News_Pic3.setImageResource(mCards.get(Index).getSubCards().get(2).getDrawable()); TextView News_Title3=(TextView)mView.findViewById(R.id.News_Title3); News_Title3.setText(mCards.get(Index).getSubCards().get(2).getDescription()); return mView; } }
Since there are three messages under each header message, we need to use the AppendCard() method to add three BaseCard s for binding here when constructing a Card, which needs to be noted when using.
Step 5: Layout of the main interface and related logic:
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- tools:context=".MainActivity" >
- <TextView
- android:layout_width="match_parent"
- android:layout_height="40dp"
- android:background="@drawable/tab_bg"
- android:gravity="center"
- android:textColor="#ffffff"
- android:textSize="18sp"
- android:text="@string/Title" />
- <ListView
- android:id="@+id/ListView"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:divider="@null"
- android:dividerHeight="30dp"
- android:paddingLeft="20dp"
- android:paddingRight="20dp"
- android:scrollbarStyle="outsideOverlay" >
- </ListView>
- </LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity" > <TextView android:layout_width="match_parent" android:layout_height="40dp" android:background="@drawable/tab_bg" android:gravity="center" android:textColor="#ffffff" android:textSize="18sp" android:text="@string/Title" /> <ListView android:id="@+id/ListView" android:layout_width="match_parent" android:layout_height="wrap_content" android:divider="@null" android:dividerHeight="30dp" android:paddingLeft="20dp" android:paddingRight="20dp" android:scrollbarStyle="outsideOverlay" > </ListView> </LinearLayout>
- /*
- * Fake WeChat Public Number Message Interface
- * Author: Qin Yuanpei
- * Time: Dec. 30, 2013
- * The principle of this program is to override the adapter and then bind the list.I think the ScrollView should be used for how WeChat works
- * The current drawbacks of this program are:
- * 1,Card The BaseCard and BaseCard classes need to be improved
- * 2,Scrollbars are not on the edge of the screen, but on the edge of the card, which means there is a problem with the method itself. [Solution: scrollbarStyle="outsideOverlay]
- * 3,The spacing between the two cards could not be resolved. Attempting to use the divider and dividerHeight attributes, found that there is a certain color difference [Solution: android:divider="@null"]
- * 4,If you want to implement that notification from WeChat, you need to add a layout, a type judgment
- * 5,Resolve memory consumption when there are more pictures
- */
- package com.Android.WeChatCard;
- import java.util.ArrayList;
- import java.util.List;
- import android.os.Bundle;
- import android.app.Activity;
- import android.view.Menu;
- import android.view.Window;
- import android.widget.ListView;
- public class MainActivity extends Activity {
- private ListView mListView;
- private CardAdapter mAdapter;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- this.requestWindowFeature(Window.FEATURE_NO_TITLE);
- setContentView(R.layout.layout_main);
- mListView=(ListView)findViewById(R.id.ListView);
- mAdapter=new CardAdapter(this,getItems());
- mListView.setAdapter(mAdapter);
- }
- private List<Card> getItems()
- {
- List<Card> mCards=new ArrayList<Card>();
- //First card
- Card mCard=new Card(R.drawable.pic_0,"This is the first headline message");
- BaseCard mBaseCard1=new BaseCard(R.drawable.pic_0,"This is the first text message");
- BaseCard mBaseCard2=new BaseCard(R.drawable.pic_0,"This is the first text message");
- BaseCard mBaseCard3=new BaseCard(R.drawable.pic_0,"This is the first text message");
- mCard.AppendCard(mBaseCard1);
- mCard.AppendCard(mBaseCard2);
- mCard.AppendCard(mBaseCard3);
- //add card
- mCards.add(mCard);
- //Second card
- mCard=new Card(R.drawable.pic_1,"This is the second headline message");
- mBaseCard1=new BaseCard(R.drawable.pic_1,"This is the first text message");
- mBaseCard2=new BaseCard(R.drawable.pic_1,"This is the first text message");
- mBaseCard3=new BaseCard(R.drawable.pic_1,"This is the first text message");
- mCard.AppendCard(mBaseCard1);
- mCard.AppendCard(mBaseCard2);
- mCard.AppendCard(mBaseCard3);
- //add card
- mCards.add(mCard);
- //Third card
- mCard=new Card(R.drawable.pic_2,"This is the third headline message");
- mBaseCard1=new BaseCard(R.drawable.pic_2,"This is the first text message");
- mBaseCard2=new BaseCard(R.drawable.pic_2,"This is the first text message");
- mBaseCard3=new BaseCard(R.drawable.pic_2,"This is the first text message");
- mCard.AppendCard(mBaseCard1);
- mCard.AppendCard(mBaseCard2);
- mCard.AppendCard(mBaseCard3);
- //add card
- mCards.add(mCard);
- //Fourth Card
- mCard=new Card(R.drawable.pic_3,"This is the fourth headline message");
- mBaseCard1=new BaseCard(R.drawable.pic_3,"This is the first text message");
- mBaseCard2=new BaseCard(R.drawable.pic_3,"This is the first text message");
- mBaseCard3=new BaseCard(R.drawable.pic_3,"This is the first text message");
- mCard.AppendCard(mBaseCard1);
- mCard.AppendCard(mBaseCard2);
- mCard.AppendCard(mBaseCard3);
- //add card
- mCards.add(mCard);
- return mCards;
- }
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- // Inflate the menu; this adds items to the action bar if it is present.
- getMenuInflater().inflate(R.menu.main, menu);
- return true;
- }
- }
/* *Fake WeChat Public Number Message Interface *Author: Qin Yuanpei *Time: Dec. 30, 2013 *The principle of this program is to override the adapter and then bind the list.I think the ScrollView should be used for how WeChat works *The current drawbacks of this program are: * 1, Card and BaseCard classes need to be improved * 2. The scrollbar is not on the edge of the screen, but on the edge of the card, which means there is a problem with the method itself. [Solution: scrollbarStyle="outsideOverlay] * 3. The spacing between two cards can not be resolved. Attempting to use divider and dividerHeight attributes, found that there is a certain color difference [Solution: android:divider="@null"] * 4. If you want to implement the WeChat notification, you need to add a layout, a type judgment * 5. Resolve memory consumption when there are more pictures */ package com.Android.WeChatCard; import java.util.ArrayList; import java.util.List; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.view.Window; import android.widget.ListView; public class MainActivity extends Activity { private ListView mListView; private CardAdapter mAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.layout_main); mListView=(ListView)findViewById(R.id.ListView); mAdapter=new CardAdapter(this,getItems()); mListView.setAdapter(mAdapter); } private List<Card> getItems() { List<Card> mCards=new ArrayList<Card>(); //First card Card mCard=new Card(R.drawable.pic_0, "This is the first headline information"); BaseCard mBaseCard1=new BaseCard(R.drawable.pic_0, "This is the first text message"); BaseCard mBaseCard2=new BaseCard(R.drawable.pic_0, "This is the first text message"); BaseCard mBaseCard3=new BaseCard(R.drawable.pic_0, "This is the first text message"); mCard.AppendCard(mBaseCard1); mCard.AppendCard(mBaseCard2); mCard.AppendCard(mBaseCard3); //Add Card mCards.add(mCard); //Second card mCard=new Card(R.drawable.pic_1, "This is the second header information"); mBaseCard1=new BaseCard(R.drawable.pic_1, "This is the first text message"); mBaseCard2=new BaseCard(R.drawable.pic_1, "This is the first text message"); mBaseCard3=new BaseCard(R.drawable.pic_1, "This is the first text message"); mCard.AppendCard(mBaseCard1); mCard.AppendCard(mBaseCard2); mCard.AppendCard(mBaseCard3); //Add Card mCards.add(mCard); //Third card mCard=new Card(R.drawable.pic_2, "This is the third headline information"); mBaseCard1=new BaseCard(R.drawable.pic_2, "This is the first text message"); mBaseCard2=new BaseCard(R.drawable.pic_2, "This is the first text message"); mBaseCard3=new BaseCard(R.drawable.pic_2, "This is the first text message"); mCard.AppendCard(mBaseCard1); mCard.AppendCard(mBaseCard2); mCard.AppendCard(mBaseCard3); //Add Card mCards.add(mCard); //Fourth card mCard=new Card(R.drawable.pic_3, "This is the fourth headline information"); mBaseCard1=new BaseCard(R.drawable.pic_3, "This is the first text message"); mBaseCard2=new BaseCard(R.drawable.pic_3, "This is the first text message"); mBaseCard3=new BaseCard(R.drawable.pic_3, "This is the first text message"); mCard.AppendCard(mBaseCard1); mCard.AppendCard(mBaseCard2); mCard.AppendCard(mBaseCard3); //Add Card mCards.add(mCard); return mCards; } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
The final result is shown in the diagram:
You can refer to this article for the implementation of the sending time of messages in micro-letters: