一、分析
最近在工作中的工商银行elife页面,该需求需要首页listView列表中的条目的标题和图表实现以下效果:

该效果类似大众点评的美食页面的一个布局:
二、实现
1.自定义一个PoiListItem继承LinearLayout
在这个类中实现listView的每一个条目中布局数据的显示。实现原理:将标题和图标嵌套在一个FrameLayout布局当中,将所有的图标显示出来,然后这个类中的方法中,控制图标的显示与否。
要想实现以上效果,在这里设置每一个图标和标题的padding属性,设置其右内边距getPaddingRight(),从而实现上述效果
2.代码实现
PoiListItem类
package com.icbc.elife.views;
import com.icbc.elife.R;
import com.icbc.elife.utils.DisplayUtil;
import com.icbc.elife.utils.ImageLoaderUtil;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RatingBar;
import android.widget.TextView;
public class PoiListItem extends LinearLayout {
private static int YIDAI_PADDING=0;
private static int SHANKU_PADDING=0;
private static int JIFEN_PADDING=0;
private static int FENQI_PADDING=0;
private static int ICBCDISCOUNT_PADDING=0;
private static int GROUP_PADDING=0;
private static int ICBCCARD_PADDING=0;
private static int CUXIAO_PADDING=0;
private static int YUDING_PADDING=0;
private ImageView logo;
private TextView name;
private TextView currentPrice;
private TextView originalPrice;
private TextView saled;
private TextView shopPrice;
private TextView smallName;
private TextView distance;
private TextView unit;
private RatingBar ratingbar;
private LinearLayout homeGuessLikeIconLayout;
private View bottomView;
private View yidai,shanku,jifen,fenqi,icbcdiscount,group,icbccard,cuxiao,yuding;
Context context;
/*holder.logo = (ImageView) view.findViewById(R.id.shop_logo);
holder.name = (TextView) view.findViewById(R.id.shop_name);
holder.smallName = (TextView) view.findViewById(R.id.small_name);
holder.distance = (TextView) view.findViewById(R.id.shop_distance);
holder.unit = (TextView) view.findViewById(R.id.shop_distance_unit);
holder.shopPrice = (TextView) view.findViewById(R.id.shop_price);
holder.ratingbar = (RatingBar) view.findViewById(R.id.shop_level);
holder.bottomView = (View) view.findViewById(R.id.bottom_view);*/
public PoiListItem(Context context, AttributeSet attrs) {
super(context, attrs);
this.context=context;
}
public PoiListItem(Context context) {
super(context);
this.context=context;
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
this.logo=(ImageView) findViewById(R.id.shop_logo);
this.name=(TextView) findViewById(R.id.shop_name);
this.smallName = (TextView)findViewById(R.id.small_name);
this.distance = (TextView)findViewById(R.id.shop_distance);
this.unit = (TextView)findViewById(R.id.shop_distance_unit);
this.shopPrice = (TextView)findViewById(R.id.shop_price);
this.ratingbar = (RatingBar)findViewById(R.id.shop_level);
this.bottomView = (View)findViewById(R.id.bottom_view);
this.yidai=findViewById(R.id.yidai);
this.shanku=findViewById(R.id.shanku);
this.jifen=findViewById(R.id.jifen);
this.fenqi=findViewById(R.id.fenqi);
this.icbcdiscount=findViewById(R.id.icbcdiscount);
this.group=findViewById(R.id.group);
this.icbccard=findViewById(R.id.icbccard);
this.cuxiao=findViewById(R.id.cuxiao);
this.yuding=findViewById(R.id.yuding);
}
public void setPoiData(String image_url, String storename, String districtName, String sallName, String distance,
String unit, String averageprice, String ratingbarcount, boolean isYidai, boolean isShanku, boolean isJifen,
boolean isFenqi, boolean isIcbcdiscount, boolean isGroup, boolean isIcbccard, boolean isCuxiao, boolean isYuding) {
int a=0;
int b=0;
int c=0;
int d=0;
int e=0;
int f=0;
int g=0;
int h=0;
int i=0;
if(image_url!=null){
ImageLoaderUtil.imageLoader(context, image_url,this.logo, ImageLoaderUtil.defaultShopType);
}
if(!"".equals(storename)&&storename!=null){
this.name.setText(storename);
}
this.smallName.setText(districtName +" "+sallName);
if(!"0.0".equals(distance)&&distance!=null){
this.distance.setText(distance);
this.unit.setText(unit);
}
if(averageprice!=null&&!"0".equals(averageprice)){
this.shopPrice.setText(averageprice+"元/人");
}
if(ratingbarcount!=null){
this.ratingbar.setRating(Float.parseFloat(ratingbarcount));
}
if(isYidai)
{
if(YIDAI_PADDING == 0)
{
//YIDAI_PADDING = BitmapFactory.decodeResource(getResources(), R.drawable.icon_yidai).getWidth();
YIDAI_PADDING = DisplayUtil.dip2px(context, 15);
YIDAI_PADDING += (int)(4.0F * getResources().getDisplayMetrics().density);
}
a = YIDAI_PADDING;
this.yidai.setVisibility(View.VISIBLE);
}
else
{
this.yidai.setVisibility(View.INVISIBLE);
}
if(isShanku)
{
if(SHANKU_PADDING == 0)
{
SHANKU_PADDING = DisplayUtil.dip2px(context, 15);
SHANKU_PADDING += (int)(4.0F * getResources().getDisplayMetrics().density);
}
a += SHANKU_PADDING;
b += SHANKU_PADDING;
this.shanku.setVisibility(View.VISIBLE);
}
else
{
this.shanku.setVisibility(View.INVISIBLE);
}
if(isJifen)
{
if(JIFEN_PADDING == 0)
{
JIFEN_PADDING = DisplayUtil.dip2px(context, 15);
JIFEN_PADDING += (int)(4.0F * getResources().getDisplayMetrics().density);
}
a += JIFEN_PADDING;
b += JIFEN_PADDING;
c += JIFEN_PADDING;
this.jifen.setVisibility(View.VISIBLE);
}
else
{
this.jifen.setVisibility(View.INVISIBLE);
}
if(isFenqi)
{
if(FENQI_PADDING == 0)
{
FENQI_PADDING = DisplayUtil.dip2px(context, 15);
FENQI_PADDING += (int)(4.0F * getResources().getDisplayMetrics().density);
}
a += FENQI_PADDING;
b += FENQI_PADDING;
c += FENQI_PADDING;
d += FENQI_PADDING;
this.fenqi.setVisibility(View.VISIBLE);
}
else
{
this.fenqi.setVisibility(View.INVISIBLE);
}
if(isIcbcdiscount)
{
if(ICBCDISCOUNT_PADDING == 0)
{
ICBCDISCOUNT_PADDING = DisplayUtil.dip2px(context, 15);
ICBCDISCOUNT_PADDING += (int)(4.0F * getResources().getDisplayMetrics().density);
}
a += ICBCDISCOUNT_PADDING;
b += ICBCDISCOUNT_PADDING;
c += ICBCDISCOUNT_PADDING;
d += ICBCDISCOUNT_PADDING;
e += ICBCDISCOUNT_PADDING;
this.icbcdiscount.setVisibility(View.VISIBLE);
}
else
{
this.icbcdiscount.setVisibility(View.INVISIBLE);
}
if(isGroup)
{
if(GROUP_PADDING == 0)
{
GROUP_PADDING = DisplayUtil.dip2px(context, 15);
GROUP_PADDING += (int)(4.0F * getResources().getDisplayMetrics().density);
}
a += GROUP_PADDING;
b += GROUP_PADDING;
c += GROUP_PADDING;
d += GROUP_PADDING;
e += GROUP_PADDING;
f += GROUP_PADDING;
this.group.setVisibility(View.VISIBLE);
}
else
{
this.group.setVisibility(View.INVISIBLE);
}
if(isIcbccard)
{
if(ICBCCARD_PADDING == 0)
{
ICBCCARD_PADDING = DisplayUtil.dip2px(context, 15);
ICBCCARD_PADDING += (int)(4.0F * getResources().getDisplayMetrics().density);
}
a += ICBCCARD_PADDING;
b += ICBCCARD_PADDING;
c += ICBCCARD_PADDING;
d += ICBCCARD_PADDING;
e += ICBCCARD_PADDING;
f += ICBCCARD_PADDING;
g += ICBCCARD_PADDING;
this.icbccard.setVisibility(View.VISIBLE);
}
else
{
this.icbccard.setVisibility(View.INVISIBLE);
}
if(isCuxiao)
{
if(CUXIAO_PADDING == 0)
{
CUXIAO_PADDING = DisplayUtil.dip2px(context, 15);
CUXIAO_PADDING += (int)(4.0F * getResources().getDisplayMetrics().density);
}
a += CUXIAO_PADDING;
b += CUXIAO_PADDING;
c += CUXIAO_PADDING;
d += CUXIAO_PADDING;
e += CUXIAO_PADDING;
f += CUXIAO_PADDING;
g += CUXIAO_PADDING;
h += CUXIAO_PADDING;
this.cuxiao.setVisibility(View.VISIBLE);
}
else
{
this.cuxiao.setVisibility(View.INVISIBLE);
}
if(isYuding)
{
if(YUDING_PADDING == 0)
{
YUDING_PADDING = DisplayUtil.dip2px(context, 15);
YUDING_PADDING += (int)(4.0F * getResources().getDisplayMetrics().density);
}
a += YUDING_PADDING;
b += YUDING_PADDING;
c += YUDING_PADDING;
d += YUDING_PADDING;
e += YUDING_PADDING;
f += YUDING_PADDING;
g += YUDING_PADDING;
h += YUDING_PADDING;
i += YUDING_PADDING;
this.yuding.setVisibility(View.VISIBLE);
}
else
{
this.yuding.setVisibility(View.INVISIBLE);
}
this.yidai.setPadding(this.yidai.getPaddingLeft(), this.yidai.getPaddingTop(), b, this.yidai.getPaddingBottom());
this.shanku.setPadding(this.shanku.getPaddingLeft(), this.shanku.getPaddingTop(), c, this.shanku.getPaddingBottom());
this.jifen.setPadding(this.jifen.getPaddingLeft(), this.jifen.getPaddingTop(), d, this.jifen.getPaddingBottom());
this.fenqi.setPadding(this.fenqi.getPaddingLeft(), this.fenqi.getPaddingTop(), e, this.fenqi.getPaddingBottom());
this.icbcdiscount.setPadding(this.icbcdiscount.getPaddingLeft(), this.icbcdiscount.getPaddingTop(), f, this.icbcdiscount.getPaddingBottom());
this.group.setPadding(this.group.getPaddingLeft(), this.group.getPaddingTop(), g, this.group.getPaddingBottom());
this.icbccard.setPadding(this.icbccard.getPaddingLeft(), this.icbccard.getPaddingTop(), h, this.icbccard.getPaddingBottom());
this.cuxiao.setPadding(this.cuxiao.getPaddingLeft(), this.cuxiao.getPaddingTop(), i, this.cuxiao.getPaddingBottom());
this.name.setPadding(this.name.getPaddingLeft(), this.name.getPaddingTop(),a,this.name.getPaddingBottom());
}
}
布局代码:
<?xml version="1.0" encoding="utf-8"?>
<com.icbc.elife.views.PoiListItem xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:minHeight="?android:listPreferredItemHeight"
android:orientation="vertical" >
<View
android:layout_width="fill_parent"
android:layout_height="1px"
android:background="@color/home_line" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="horizontal" >
<RelativeLayout
android:layout_width="100dp"
android:layout_height="75dp" >
<ImageView
android:id="@+id/shop_logo"
android:layout_width="100dp"
android:layout_height="75dp"
android:scaleType="fitXY" />
</RelativeLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="77dp"
android:layout_marginLeft="10dp"
android:orientation="vertical" >
<FrameLayout
android:id="@+id/home_guess_like_icon_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/shop_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:gravity="center"
android:layout_marginRight="5dp"
android:singleLine="true"
android:text=""
android:textAppearance="?android:textAppearanceMedium"
android:textColor="#333333"
android:textSize="16dp" />
<ImageView
android:id="@+id/yidai"
android:layout_width="wrap_content"
android:layout_height="15dp"
android:layout_gravity="right|center"
android:src="@drawable/icon_yidai" />
<ImageView
android:id="@+id/shanku"
android:layout_width="wrap_content"
android:layout_height="15dp"
android:layout_gravity="right|center"
android:src="@drawable/icon_shan" />
<ImageView
android:id="@+id/jifen"
android:layout_width="wrap_content"
android:layout_height="15dp"
android:layout_gravity="right|center"
android:src="@drawable/icon_jifen" />
<ImageView
android:id="@+id/fenqi"
android:layout_width="wrap_content"
android:layout_height="15dp"
android:layout_gravity="right|center"
android:src="@drawable/icon_fenqi" />
<ImageView
android:id="@+id/icbcdiscount"
android:layout_width="wrap_content"
android:layout_height="15dp"
android:layout_gravity="right|center"
android:src="@drawable/icon_icbc" />
<ImageView
android:id="@+id/group"
android:layout_width="wrap_content"
android:layout_height="15dp"
android:layout_gravity="right|center"
android:src="@drawable/icon_tuan" />
<ImageView
android:id="@+id/icbccard"
android:layout_width="wrap_content"
android:layout_height="15dp"
android:layout_gravity="right|center"
android:src="@drawable/icon_ka" />
<ImageView
android:id="@+id/cuxiao"
android:layout_width="wrap_content"
android:layout_height="15dp"
android:layout_gravity="right|center"
android:src="@drawable/icon_cuxiao" />
<ImageView
android:id="@+id/yuding"
android:layout_width="wrap_content"
android:layout_height="15dp"
android:layout_gravity="right|center"
android:src="@drawable/icon_yuding" />
<!--
<LinearLayout
android:id="@+id/home_guess_like_icon_layout"
android:layout_width="wrap_content"
android:layout_height="15dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:gravity="right"
android:orientation="horizontal"
android:visibility="visible" >
</LinearLayout>
-->
</FrameLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="horizontal" >
<RatingBar
android:id="@+id/shop_level"
style="@style/homeRecommmendRatingBar"
android:layout_width="wrap_content"
android:layout_height="16dp"
android:clickable="false"
android:maxHeight="16dp"
android:minHeight="10dp"
android:numStars="5" />
<TextView
android:id="@+id/shop_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_weight="1"
android:gravity="right"
android:text=""
android:textColor="#333333"
android:textSize="14dp" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="horizontal" >
<TextView
android:id="@+id/small_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:singleLine="true"
android:text=""
android:textColor="#999999"
android:textSize="@dimen/home_small_size" />
<TextView
android:id="@+id/shop_distance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text=""
android:textColor="@color/home_text_hint"
android:textSize="@dimen/home_small_size" />
<TextView
android:id="@+id/shop_distance_unit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:textColor="@color/home_text_hint"
android:textSize="@dimen/home_small_size" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<View
android:id="@+id/bottom_view"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="#E2E2E2"
android:visibility="gone" >
</View>
</com.icbc.elife.views.PoiListItem>
getView()方法的实现
public View getView(int position, View view, ViewGroup arg2) {
if(view==null){
Log.v("is NULL","DF2"+position);
}
Log.v("ListViewLog","DF"+position);
view = LayoutInflater.from(context).inflate(
R.layout.home_recommend_shop_item, null);
// FrameLayout home_guess_like_icon_layout = (FrameLayout) view.findViewById(R.id.home_guess_like_icon_layout);
// home_guess_like_icon_layout.removeAllViews();
final GuessYouLike item = getItem(position);
if(!"".equals(list.get(position).getService_logos())&&list.get(position).getService_logos()!=null){
System.out.println("图标大小为"+list.get(position).getService_logos().size());
for(int i = 0 ;i<list.get(position).getService_logos().size() ;i++){
String str = list.get(position).getService_logos().get(i).getImage_icon();
if("YIDAI".equals(str)){
isYidai=true;
}
if("SHANKU".equals(str)){
isShanku=true;
}
if("JIFEN".equals(str)){
isJifen=true;
}
if("FENQI".equals(str)){
isFenqi=true;
}
if("ICBCDISCOUNT".equals(str)){
isIcbcdiscount=true;
}
if("GROUP".equals(str)){
isGroup=true;
}
if("ICBCCARD".equals(str)){
isIcbccard=true;
}
if("CUXIAO".equals(str)){
isCuxiao=true;
}
if("YUDING".equals(str)){
isYuding=true;
}
if(i>=6){
break;
}
}
}
System.out.println("isYidai:"+isYidai+"---isShanku:"+isShanku+"---isJifen:"+isJifen+"---isFenqi:"+isFenqi+"---isIcbcdiscount:"+isIcbcdiscount+"---isGroup:"+isGroup+"---isIcbccard:"+isIcbccard+"---isCuxiao:"+isCuxiao+"---isYuding:"+isYuding);
String districtName = "";
districtName = (item.getDistrict_name1()==null||"".equals(item.getDistrict_name1()))?"":item.getDistrict_name1();
districtName += (item.getDistrict_name2()==null||"".equals(item.getDistrict_name2()))?"":"/"+item.getDistrict_name2();
districtName += (item.getDistrict_name3()==null||"".equals(item.getDistrict_name3()))?"":"/"+item.getDistrict_name3();
if(districtName.contains("/")&&"/".equals(districtName.substring(0, 1))){
districtName = districtName.substring(1,districtName.length());
}
String sallName = "";
sallName = (item.getSmall_name1()==null||"".equals(item.getSmall_name1()))?"":item.getSmall_name1();
sallName += (item.getSmall_name2()==null||"".equals(item.getSmall_name2()))?"":"/"+item.getSmall_name2();
sallName += (item.getSmall_name3()==null||"".equals(item.getSmall_name3()))?"":"/"+item.getSmall_name3();
if(sallName.contains("/")&&"/".equals(sallName.substring(0, 1))){
sallName = sallName.substring(1,sallName.length());
}
String distance=""; //距离
String unit="";
distance=item.getDistance();
unit=item.getUnit();
String averageprice=""; //平均价格
averageprice=item.getAverage_price();
String ratingbarcount; //星级个数
ratingbarcount=item.getLevels();
String storename=""; //店铺名称
storename=item.getStore_name();
PoiListItem pItem=(PoiListItem) view;
pItem.setPoiData(item.getImage_url(),storename,districtName,sallName,
distance,unit,averageprice,ratingbarcount,
isYidai,isShanku,isJifen,isFenqi,isIcbcdiscount,isGroup,isIcbccard,
isCuxiao,isYuding);
isYidai=isShanku=isJifen=isFenqi=isIcbcdiscount=isGroup=isIcbccard=isCuxiao=isYuding=false;
return view;
}
三、扩展
与上述情况不同的是,另外一种情况是图标靠近右侧的边上显示,这种效果的实现步骤如下
1.首先要实现这种效果,要将图标优先显示出来
2.将标题和图表嵌套在一个相对布局里面,然后设置标题TextView的属性为:singleLine="true",android:ellipsize="end"
设置图标ImageView的属性为:android:layout_alignParentRight="true"
3.然后设置标题TextView相对于ImageView在左边(toLeftOf),这样就能够实现标题和图表的这种效果了