Android开发学习之微信公众号界面

接着上一篇博客中的卡片式设计,我们继续从微信中寻找一些线索,我们首先来看这样一个界面,这是微信中默认的一个公众号,主要是发布腾讯新闻上的最新动态,我们可以看出,它采用了类似于我们在上一篇文章中采用的卡片式布局。那么,今天就让我们一起来做这样一个界面吧!


第一步,当然是创建layout_item的布局,即列表项目的布局,这里直接给出布局代码,代码并不复杂,只是属性设置较为繁琐。

<?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>

第二步,我们需要为卡片编写一个圆角的形状radius_bg。代码和上一篇文章是一样的

<?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>
第三步,卡片类,这里卡片类共有两个,BaseCard为基类,Card为继承自BaseCard的一个类:

/*
 * 仿微信公众平台消息界面
 * @作者:秦元培
 * 
 */
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;
	}

}

第四步,我们来编写自定义适配器类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);
		     //头条消息
		     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());
		     //消息一
		     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());
		     //消息二
		     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());
		     //消息三
		    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;
	}
}

由于每个头条消息下有三个消息,因此我们需要在构造Card的时候,使用AppendCard()方法添加三个BaseCard供这里绑定使用,这一点在使用的时候需要注意。

第五步,主界面的布局和相关逻辑:

<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>

/*
 * 仿微信公众号消息界面
 * 作者:秦元培
 * 时间:2013年12月30日
 * 这个程序的原理是重写适配器,然后绑定列表。我觉得微信的实现原理应该使用的ScrollView吧
 * 这个程序目前的缺点有:
 * 1、Card和BaseCard两个类还需要完善
 * 2、滚动条不是在屏幕边缘,而是在卡片边缘,也就是说这个方法本身有问题.[解决方法:scrollbarStyle="outsideOverlay]
 * 3、两个卡片间的间距问题无法解决,尝试着用了divider和dividerHeight属性,发现有一定的色差[解决方法:android:divider="@null"]
 * 4、如果要实现微信的那个通知,需要增加一个布局、一个类型判断
 * 5、当图片较多时解决内存消耗的问题
 */
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>();
		//第一个卡片
		Card mCard=new Card(R.drawable.pic_0,"这是第一个头条信息");
		BaseCard mBaseCard1=new BaseCard(R.drawable.pic_0,"这是第一个文本消息");
		BaseCard mBaseCard2=new BaseCard(R.drawable.pic_0,"这是第一个文本消息");
		BaseCard mBaseCard3=new BaseCard(R.drawable.pic_0,"这是第一个文本消息");
		mCard.AppendCard(mBaseCard1);
		mCard.AppendCard(mBaseCard2);
		mCard.AppendCard(mBaseCard3);
		//添加卡片
		mCards.add(mCard);

		//第二个卡片
		mCard=new Card(R.drawable.pic_1,"这是第二个头条信息");
		mBaseCard1=new BaseCard(R.drawable.pic_1,"这是第一个文本消息");
		mBaseCard2=new BaseCard(R.drawable.pic_1,"这是第一个文本消息");
		mBaseCard3=new BaseCard(R.drawable.pic_1,"这是第一个文本消息");
		mCard.AppendCard(mBaseCard1);
		mCard.AppendCard(mBaseCard2);
		mCard.AppendCard(mBaseCard3);
		//添加卡片
		mCards.add(mCard);

		//第三个卡片
		mCard=new Card(R.drawable.pic_2,"这是第三个头条信息");
		mBaseCard1=new BaseCard(R.drawable.pic_2,"这是第一个文本消息");
		mBaseCard2=new BaseCard(R.drawable.pic_2,"这是第一个文本消息");
		mBaseCard3=new BaseCard(R.drawable.pic_2,"这是第一个文本消息");
		mCard.AppendCard(mBaseCard1);
		mCard.AppendCard(mBaseCard2);
		mCard.AppendCard(mBaseCard3);
		//添加卡片
		mCards.add(mCard);
		
		
		//第四个卡片
		mCard=new Card(R.drawable.pic_3,"这是第四个头条信息");
		mBaseCard1=new BaseCard(R.drawable.pic_3,"这是第一个文本消息");
		mBaseCard2=new BaseCard(R.drawable.pic_3,"这是第一个文本消息");
		mBaseCard3=new BaseCard(R.drawable.pic_3,"这是第一个文本消息");
		mCard.AppendCard(mBaseCard1);
		mCard.AppendCard(mBaseCard2);
		mCard.AppendCard(mBaseCard3);
		//添加卡片
		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;
	}

}

最终运行效果如图所示:


至于微信中的消息发送时间的实现,大家可以参考这篇文章:

http://blog.csdn.net/qinyuanpei/article/details/17727767

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值