android listview 圆角的实现方案,模仿Iphone的UITableView

需求         

这几天十一放假,在群里非常活跃,很多朋友问如何实现android中listview的圆角功能,像Iphone设置里面的tableView如 如下效果:

         

   

实现过程

其实这个功能实现也很简单,只是很多朋友没有仔细的去了解android布局的相关知识,这里我们使用了android中的shade的圆角功能来实现的。

  java代码很简单,就一个activity,一个listview。listview中要判断item的位置,第一条,最后一条和中间的item是不一样的。代码如下:

   java代码和布局文件

AndroidlistviewActivity.java

  1. package com.yangfuhai.listviewdemo; 
  2.  
  3. import android.app.Activity; 
  4. import android.os.Bundle; 
  5. import android.view.View; 
  6. import android.widget.ListView; 
  7. /**
  8. * @title 圆角listview的实现
  9. * @description 圆角listview的实现
  10. * @company 探索者网络工作室(www.tsz.net)
  11. * @author michael Young (www.YangFuhai.com)
  12. * @version 1.0
  13. * @created 2012-10-3
  14. */ 
  15. publicclass AndroidlistviewActivity extends Activity { 
  16.     ListView mListView; 
  17.     ListViewAdapter mListViewAdapter; 
  18.  
  19.     @Override 
  20.     publicvoid onCreate(Bundle savedInstanceState) { 
  21.         super.onCreate(savedInstanceState); 
  22.         setContentView(R.layout.main); 
  23.         mListView = (ListView) findViewById(R.id.listview); 
  24.         mListViewAdapter = new ListViewAdapter(this); 
  25.         mListView.setAdapter(mListViewAdapter); 
  26.     } 
  27.  
  28.     /**
  29.      * 添加 按钮执行的操作
  30.      * @param view
  31.      */ 
  32.     staticint i = 0
  33.     publicvoid add(View view) { 
  34.         mListViewAdapter.addData(" ----item ---   "+i+"   ---"); 
  35.         mListViewAdapter.notifyDataSetChanged(); 
  36.         i++; 
  37.     } 
  38.  
  39.     /**
  40.      * 删除按钮执行的操作
  41.      * @param view
  42.      */ 
  43.     publicvoid del(View view) { 
  44.         mListViewAdapter.delData(); 
  45.         mListViewAdapter.notifyDataSetChanged(); 
  46.         if(i>0) i--; 
  47.     } 
package com.yangfuhai.listviewdemo;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ListView;
/**
 * @title 圆角listview的实现
 * @description 圆角listview的实现
 * @company 探索者网络工作室(www.tsz.net)
 * @author michael Young (www.YangFuhai.com)
 * @version 1.0
 * @created 2012-10-3
 */
public class AndroidlistviewActivity extends Activity {
	ListView mListView;
	ListViewAdapter mListViewAdapter;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		mListView = (ListView) findViewById(R.id.listview);
		mListViewAdapter = new ListViewAdapter(this);
		mListView.setAdapter(mListViewAdapter);
	}

	/**
	 * 添加 按钮执行的操作
	 * @param view
	 */
	static int i = 0;
	public void add(View view) {
		mListViewAdapter.addData(" ----item ---   "+i+"   ---");
		mListViewAdapter.notifyDataSetChanged();
		i++;
	}

	/**
	 * 删除按钮执行的操作
	 * @param view
	 */
	public void del(View view) {
		mListViewAdapter.delData();
		mListViewAdapter.notifyDataSetChanged();
		if(i>0) i--;
	}
}

适配器 ListViewAdapter.java

  1. package com.yangfuhai.listviewdemo; 
  2.  
  3. import java.util.ArrayList; 
  4. import java.util.List; 
  5.  
  6. import android.content.Context; 
  7. import android.view.View; 
  8. import android.view.ViewGroup; 
  9. import android.widget.BaseAdapter; 
  10. import android.widget.TextView; 
  11. /**
  12. * @title 圆角listview的实现 适配器
  13. * @description ListViewAdapter listview的适配器
  14. * @company 探索者网络工作室(www.tsz.net)
  15. * @author michael Young (www.YangFuhai.com)
  16. * @version 1.0
  17. * @created 2012-10-3
  18. */ 
  19. publicclass ListViewAdapter extends BaseAdapter { 
  20.      
  21.     private List<String> datas = new ArrayList<String>(); //数据  
  22.     private Context mContext; 
  23.     public ListViewAdapter(Context c) { 
  24.         this.mContext = c; 
  25.     } 
  26.     publicvoid addData(String strData){ 
  27.         if(strData!=null) datas.add(strData); 
  28.     } 
  29.      
  30.     publicvoid delData(){ 
  31.         if(datas.size() > 0) datas.remove(datas.size() - 1); 
  32.     } 
  33.      
  34.     @Override 
  35.     publicint getCount() { 
  36.         return datas.size(); 
  37.     } 
  38.  
  39.     @Override 
  40.     public Object getItem(int arg0) { 
  41.         return datas.get(arg0); 
  42.     } 
  43.  
  44.     @Override 
  45.     publiclong getItemId(int position) { 
  46.         return position; 
  47.     } 
  48.  
  49.     /**
  50.      * listview中要判断item的位置,第一条,最后一条和中间的item是不一样的。
  51.      */ 
  52.     @Override 
  53.     public View getView(int position, View convertView, ViewGroup parent) { 
  54.         View view  = null
  55.         if(datas.size()>1){//listView 数据是两条以上  
  56.             if(position == 0){ //第一条数据  
  57.                 view = View.inflate(mContext, R.layout.list_item_top, null); 
  58.             }elseif(position == datas.size() - 1){ //最后一条数据  
  59.                 view = View.inflate(mContext, R.layout.list_item_bottom, null); 
  60.             }else{ //中间的数据  
  61.                 view = View.inflate(mContext, R.layout.list_item_middle, null); 
  62.             } 
  63.         }else{ //只有一条数据  
  64.             view = View.inflate(mContext, R.layout.list_item_single, null); 
  65.         } 
  66.          
  67.         ((TextView)view.findViewById(R.id.title)).setText(datas.get(position));//设置文本样式  
  68.         return view; 
  69.     } 
  70.  
package com.yangfuhai.listviewdemo;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
/**
 * @title 圆角listview的实现 适配器
 * @description ListViewAdapter listview的适配器
 * @company 探索者网络工作室(www.tsz.net)
 * @author michael Young (www.YangFuhai.com)
 * @version 1.0
 * @created 2012-10-3
 */
public class ListViewAdapter extends BaseAdapter {
	
	private List<String> datas = new ArrayList<String>(); //数据
	private Context mContext;
	public ListViewAdapter(Context c) {
		this.mContext = c;
	}
	public void addData(String strData){
		if(strData!=null) datas.add(strData);
	}
	
	public void delData(){
		if(datas.size() > 0) datas.remove(datas.size() - 1);
	}
	
	@Override
	public int getCount() {
		return datas.size();
	}

	@Override
	public Object getItem(int arg0) {
		return datas.get(arg0);
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	/**
	 * listview中要判断item的位置,第一条,最后一条和中间的item是不一样的。
	 */
	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		View view  = null ;
		if(datas.size()>1){//listView 数据是两条以上
			if(position == 0){ //第一条数据
				view = View.inflate(mContext, R.layout.list_item_top, null);
			}else if(position == datas.size() - 1){ //最后一条数据
				view = View.inflate(mContext, R.layout.list_item_bottom, null);
			}else{ //中间的数据
				view = View.inflate(mContext, R.layout.list_item_middle, null);
			}
		}else{ //只有一条数据
			view = View.inflate(mContext, R.layout.list_item_single, null);
		}
		
		((TextView)view.findViewById(R.id.title)).setText(datas.get(position));//设置文本样式
		return view;
	}

}

布局文件main.xml

  1. <?xmlversion="1.0"encoding="utf-8"?> 
  2. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" 
  3.     android:layout_width="wrap_content" 
  4.     android:layout_height="fill_parent" 
  5.     android:orientation="vertical"> 
  6.  
  7.     <TextView 
  8.         android:layout_width="fill_parent" 
  9.         android:layout_height="wrap_content" 
  10.         android:text="请点击添加删除 查看效果"/> 
  11.  
  12.     <LinearLayout 
  13.         android:layout_width="match_parent" 
  14.         android:layout_height="wrap_content" 
  15.         android:gravity="center"> 
  16.  
  17.         <Button 
  18.             android:id="@+id/buttonAdd" 
  19.             android:layout_width="wrap_content" 
  20.             android:layout_height="wrap_content" 
  21.             android:onClick="add" 
  22.             android:text="添加"/> 
  23.  
  24.         <Button 
  25.             android:id="@+id/buttonDel" 
  26.             android:layout_width="wrap_content" 
  27.             android:layout_height="wrap_content" 
  28.             android:onClick="del" 
  29.             android:text="删除"/> 
  30.     </LinearLayout> 
  31.  
  32.     <ListView 
  33.         android:id="@+id/listview" 
  34.         android:layout_marginLeft="10dip" 
  35.         android:layout_marginRight="10dip" 
  36.         android:layout_width="fill_parent" 
  37.         android:layout_height="wrap_content"/> 
  38.  
  39. </LinearLayout> 
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="请点击添加删除 查看效果" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center" >

        <Button
            android:id="@+id/buttonAdd"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="add"
            android:text="添加" />

        <Button
            android:id="@+id/buttonDel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="del"
            android:text="删除" />
    </LinearLayout>

    <ListView
        android:id="@+id/listview"
        android:layout_marginLeft="10dip"
        android:layout_marginRight="10dip"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

listview的布局文件和资源文件

上面的代码很简单,没有什么可讲的。主要讲的是listview每个item的样式文件

listview的item有四个布局文件,分别是:只有一个item时候的样式,多个item时候上边item的样式,下边item的样式,中间item的样式。 布局文件和背景文件对应关系如下图所示:

文件文件

listview的item布局样式如下:

  1. <?xmlversion="1.0"encoding="utf-8"?> 
  2. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" 
  3.     style="@style/list_item_middle" 
  4.     android:layout_width="fill_parent" 
  5.     android:layout_height="wrap_content" 
  6.     android:minHeight="60dip" 
  7.     > 
  8.  
  9.     <TextView 
  10.         android:id="@+id/title" 
  11.         style="@style/content_page_large_text" 
  12.         android:layout_width="match_parent" 
  13.         android:layout_height="wrap_content" 
  14.         android:text="title"/> 
  15.  
  16. </LinearLayout> 
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    style="@style/list_item_middle"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:minHeight="60dip"
    >

    <TextView
        android:id="@+id/title"
        style="@style/content_page_large_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="title" />

</LinearLayout>

这四个布局文件中唯一不同的只是他们的stype属性(style="@style/list_item_middle")不同,也就是他们的背景不同。

资源文件

下面我们先贴出布局文件背景文件的shade代码,然后再仔细的讲解背景这些文件里面代码的意思。

background_view_rounded_bottom.xml

  1. <?xmlversion="1.0"encoding="UTF-8"?> 
  2. <insetxmlns:android="http://schemas.android.com/apk/res/android" 
  3.     android:insetBottom="1.0px" 
  4.     android:insetLeft="1.0px" 
  5.     android:insetRight="1.0px" 
  6.     android:insetTop="1.0px"> 
  7.  
  8.     <selector> 
  9.         <itemandroid:state_pressed="true"> 
  10.             <shape> 
  11.                 <gradient 
  12.                     android:angle="270.0" 
  13.                     android:endColor="@color/base_end_color_pressed" 
  14.                     android:startColor="@color/base_start_color_pressed"/> 
  15.  
  16.                 <corners 
  17.                     android:bottomLeftRadius="10.0dip" 
  18.                     android:bottomRightRadius="10.0dip" 
  19.                     android:radius="2.0dip" 
  20.                     android:topLeftRadius="0.0dip" 
  21.                     android:topRightRadius="0.0dip"/> 
  22.             </shape> 
  23.         </item> 
  24.         <item> 
  25.             <shape> 
  26.                 <gradient 
  27.                     android:angle="270.0" 
  28.                     android:endColor="@color/base_end_color_default" 
  29.                     android:startColor="@color/base_start_color_default"/> 
  30.  
  31.                 <corners 
  32.                     android:bottomLeftRadius="11.0dip" 
  33.                     android:bottomRightRadius="11.0dip" 
  34.                     android:radius="2.0dip" 
  35.                     android:topLeftRadius="0.0dip" 
  36.                     android:topRightRadius="0.0dip"/> 
  37.             </shape> 
  38.         </item> 
  39.     </selector> 
  40.  
  41. </inset> 
<?xml version="1.0" encoding="UTF-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:insetBottom="1.0px"
    android:insetLeft="1.0px"
    android:insetRight="1.0px"
    android:insetTop="1.0px" >

    <selector>
        <item android:state_pressed="true">
            <shape>
                <gradient
                    android:angle="270.0"
                    android:endColor="@color/base_end_color_pressed"
                    android:startColor="@color/base_start_color_pressed" />

                <corners
                    android:bottomLeftRadius="10.0dip"
                    android:bottomRightRadius="10.0dip"
                    android:radius="2.0dip"
                    android:topLeftRadius="0.0dip"
                    android:topRightRadius="0.0dip" />
            </shape>
        </item>
        <item>
            <shape>
                <gradient
                    android:angle="270.0"
                    android:endColor="@color/base_end_color_default"
                    android:startColor="@color/base_start_color_default" />

                <corners
                    android:bottomLeftRadius="11.0dip"
                    android:bottomRightRadius="11.0dip"
                    android:radius="2.0dip"
                    android:topLeftRadius="0.0dip"
                    android:topRightRadius="0.0dip" />
            </shape>
        </item>
    </selector>

</inset>

background_view_rounded_middle.xml:

  1. <?xmlversion="1.0"encoding="UTF-8"?> 
  2. <insetxmlns:android="http://schemas.android.com/apk/res/android" 
  3.     android:insetBottom="0.0px" 
  4.     android:insetLeft="1.0px" 
  5.     android:insetRight="1.0px" 
  6.     android:insetTop="1.0px"> 
  7.  
  8.     <selector> 
  9.         <itemandroid:state_pressed="true"> 
  10.             <shape> 
  11.                 <gradient 
  12.                     android:angle="270.0" 
  13.                     android:endColor="@color/base_end_color_pressed" 
  14.                     android:startColor="@color/base_start_color_pressed"/> 
  15.  
  16.                 <cornersandroid:radius="0.0dip"/> 
  17.             </shape> 
  18.         </item> 
  19.         <item> 
  20.             <shape> 
  21.                 <gradient 
  22.                     android:angle="270.0" 
  23.                     android:endColor="@color/base_end_color_default" 
  24.                     android:startColor="@color/base_start_color_default"/> 
  25.  
  26.                 <cornersandroid:radius="0.0dip"/> 
  27.             </shape> 
  28.         </item> 
  29.     </selector> 
  30.  
  31. </inset> 
<?xml version="1.0" encoding="UTF-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:insetBottom="0.0px"
    android:insetLeft="1.0px"
    android:insetRight="1.0px"
    android:insetTop="1.0px" >

    <selector>
        <item android:state_pressed="true">
            <shape>
                <gradient
                    android:angle="270.0"
                    android:endColor="@color/base_end_color_pressed"
                    android:startColor="@color/base_start_color_pressed" />

                <corners android:radius="0.0dip" />
            </shape>
        </item>
        <item>
            <shape>
                <gradient
                    android:angle="270.0"
                    android:endColor="@color/base_end_color_default"
                    android:startColor="@color/base_start_color_default" />

                <corners android:radius="0.0dip" />
            </shape>
        </item>
    </selector>

</inset>

background_view_rounded_single.xml :

  1. <?xmlversion="1.0"encoding="UTF-8"?> 
  2. <insetxmlns:android="http://schemas.android.com/apk/res/android" 
  3.     android:insetBottom="1.0px" 
  4.     android:insetLeft="1.0px" 
  5.     android:insetRight="1.0px" 
  6.     android:insetTop="0.0px"> 
  7.  
  8.     <selector> 
  9.         <itemandroid:state_pressed="true"> 
  10.             <shape> 
  11.                 <gradient 
  12.                     android:angle="270.0" 
  13.                     android:endColor="@color/base_end_color_pressed" 
  14.                     android:startColor="@color/base_start_color_pressed"/> 
  15.  
  16.                 <cornersandroid:radius="11.0dip"/> 
  17.             </shape> 
  18.         </item> 
  19.         <item> 
  20.             <shape> 
  21.                 <stroke 
  22.                     android:width="1.0px" 
  23.                     android:color="@color/rounded_container_border"/> 
  24.  
  25.                 <gradient 
  26.                     android:angle="270.0" 
  27.                     android:endColor="@color/base_end_color_default" 
  28.                     android:startColor="@color/base_start_color_default"/> 
  29.  
  30.                 <cornersandroid:radius="10.0dip"/> 
  31.             </shape> 
  32.         </item> 
  33.     </selector> 
  34.  
  35. </inset> 
<?xml version="1.0" encoding="UTF-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:insetBottom="1.0px"
    android:insetLeft="1.0px"
    android:insetRight="1.0px"
    android:insetTop="0.0px" >

    <selector>
        <item android:state_pressed="true">
            <shape>
                <gradient
                    android:angle="270.0"
                    android:endColor="@color/base_end_color_pressed"
                    android:startColor="@color/base_start_color_pressed" />

                <corners android:radius="11.0dip" />
            </shape>
        </item>
        <item>
            <shape>
                <stroke
                    android:width="1.0px"
                    android:color="@color/rounded_container_border" />

                <gradient
                    android:angle="270.0"
                    android:endColor="@color/base_end_color_default"
                    android:startColor="@color/base_start_color_default" />

                <corners android:radius="10.0dip" />
            </shape>
        </item>
    </selector>

</inset>

background_view_rounded_top.xml :

  1. <?xmlversion="1.0"encoding="UTF-8"?> 
  2. <insetxmlns:android="http://schemas.android.com/apk/res/android" 
  3.     android:insetBottom="0.0px" 
  4.     android:insetLeft="1.0px" 
  5.     android:insetRight="1.0px" 
  6.     android:insetTop="1.0px"> 
  7.  
  8.     <selector> 
  9.         <itemandroid:state_pressed="true"> 
  10.             <shape> 
  11.                 <gradient 
  12.                     android:angle="270.0" 
  13.                     android:endColor="@color/base_end_color_pressed" 
  14.                     android:startColor="@color/base_start_color_pressed"/> 
  15.  
  16.                 <corners 
  17.                     android:bottomLeftRadius="0.0dip" 
  18.                     android:bottomRightRadius="0.0dip" 
  19.                     android:radius="2.0dip" 
  20.                     android:topLeftRadius="10.0dip" 
  21.                     android:topRightRadius="10.0dip"/> 
  22.             </shape> 
  23.         </item> 
  24.         <item> 
  25.             <shape> 
  26.                 <gradient 
  27.                     android:angle="270.0" 
  28.                     android:endColor="@color/base_end_color_default" 
  29.                     android:startColor="@color/base_start_color_default"/> 
  30.  
  31.                 <corners 
  32.                     android:bottomLeftRadius="0.0dip" 
  33.                     android:bottomRightRadius="0.0dip" 
  34.                     android:radius="2.0dip" 
  35.                     android:topLeftRadius="11.0dip" 
  36.                     android:topRightRadius="11.0dip"/> 
  37.             </shape> 
  38.         </item> 
  39.     </selector> 
  40.  
  41. </inset> 
<?xml version="1.0" encoding="UTF-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:insetBottom="0.0px"
    android:insetLeft="1.0px"
    android:insetRight="1.0px"
    android:insetTop="1.0px" >

    <selector>
        <item android:state_pressed="true">
            <shape>
                <gradient
                    android:angle="270.0"
                    android:endColor="@color/base_end_color_pressed"
                    android:startColor="@color/base_start_color_pressed" />

                <corners
                    android:bottomLeftRadius="0.0dip"
                    android:bottomRightRadius="0.0dip"
                    android:radius="2.0dip"
                    android:topLeftRadius="10.0dip"
                    android:topRightRadius="10.0dip" />
            </shape>
        </item>
        <item>
            <shape>
                <gradient
                    android:angle="270.0"
                    android:endColor="@color/base_end_color_default"
                    android:startColor="@color/base_start_color_default" />

                <corners
                    android:bottomLeftRadius="0.0dip"
                    android:bottomRightRadius="0.0dip"
                    android:radius="2.0dip"
                    android:topLeftRadius="11.0dip"
                    android:topRightRadius="11.0dip" />
            </shape>
        </item>
    </selector>

</inset>

listview资源文件讲解

我们拿 background_view_rounded_top.xml (最后一个资源文件)来给大家讲解 里面的每个属性的含义:

inset

inset:这种资源指向一个InsetDrawable对象,它能够用指定的距离嵌入到另一个可绘制资源中。它的属性有:

android:drawable="@drawable/drawable_resource"         android:insetTop="dimension"         android:insetRight="dimension"         android:insetBottom="dimension"         android:insetLeft="dimension" 其中android:drawable是要嵌入的图片资源,android:insetXXX是嵌入位置。

selector

selector:是一种样式选择器,它用来指导某个view(button,textview,edittext等)的不同状态(比如:正常的状态,获得焦点的状态,按下的状态 等)对应的不同资源。

shade

shade gradient

shade gradient:颜色渐变 android:startColor和android:endColor分别为渐变的起始颜色和结束颜色 android:angle是渐变角度,必须为45的整数倍 。 渐变模式有两种: android:type="linear",线性渐变,白话就是渐变是从一头到另一头的颜色渐变过程。 android:type="radial",径向渐变,白话就是渐变是从中心到四周的过程。径向渐变需要指定渐变半径android:gradientRadius="50"。

shade corners

shade  corners:圆角 (这篇文章主要就是用到了它) android:radius为角的弧度,值越大角越圆。

其他

shade  除了gradient和corners以外,还有stroke(描边),solid (实心),padding等(具体大家可以看android的帮助文档)。

实现效果图

通过以上的代码,我们实现了效果如下图:

完毕

源码下载

源码下载:http://download.csdn.net/detail/michael_yy/4614701 (免积分下载)

转载请注明出处。http://blog.csdn.net/michael_yy/article/details/8038653 

http://www.yangfuhai.com/topic/48.html (杨福海的博客)

原文地址:https://www.cnblogs.com/LiaoHao/p/3291446.html