Android 仿照IOS的分段控件SegmentContro(自定义控件 + 事件监听 + 背景选择器)

        在做项目的过程中,为了使界面美观,仿照IOS系统中的分段控件,写了一个android版的如下图:

                                      

   1框架结构

                                                        

     2 主要类SegmentControlView.java文件

        整体为自定义控件,继承LinearLayout,主要完成的功能有 初始化组件,设定组件的大小,给组件添加文字和颜色和大小,给组件设置背景选择器,组件在布局中的位置,在布局中添加组件,添加自定义控件事件监听。      

package com.example.testsegmentcontrol;

import org.xmlpull.v1.XmlPullParser;



import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.ColorStateList;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.view.View.OnClickListener;

public class SegmentView  extends LinearLayout {

     private TextView lateone = null;      //最近一周
     private TextView latetwo = null;      //最近一月
     private TextView latethree = null;    //最近三月
     private  View     line = null;        //竖线
     private  View     line1 = null;       //竖线
     private Onsegmentlistenerclicker  listener;
     private   SegmentView view1 = null;
     public SegmentView(Context context) {
		super(context);
		init();
		// TODO Auto-generated constructor stub
	}
     
     public SegmentView(Context context, AttributeSet attrs) {
  		super(context, attrs);
  		init();
  	}
  	
  	@SuppressLint("NewApi")
 	public SegmentView(Context context, AttributeSet attrs, int defStyleAttr) {
  		super(context, attrs, defStyleAttr);
  		init();
  	}
     //初始化
      public void init(){
      lateone = new TextView(getContext());
      latetwo = new TextView(getContext());
      latethree =   new TextView(getContext());
      line     =  new TextView(getContext());
      line1   =  new TextView(getContext());
      
      //用來描述控件的大小
      lateone.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT,1)); //参数为宽度和高度
      line.setLayoutParams(new LayoutParams(1,LayoutParams.MATCH_PARENT));
      latetwo.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT,1));
      line1.setLayoutParams(new LayoutParams(1,LayoutParams.MATCH_PARENT));
      latethree.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT,1));
      
      //添加控件文字及大小
      lateone.setText("最近一周");
      latetwo.setText("最近一月");
      latethree.setText("最近三月");
      lateone.setTextSize(16);
      latetwo.setTextSize(16);
      latethree.setTextSize(16);
      //设置文字的颜色
		XmlPullParser xrp = getResources().getXml(R.drawable.changewenzi); 
	    try {  
	        ColorStateList csl = ColorStateList.createFromXml(getResources(), xrp);  
	        lateone.setTextColor(csl);
	        latetwo.setTextColor(csl);
	        latethree.setTextColor(csl);
	      } catch (Exception e) {  
	    } 
      
      //控件在布局中的位置
      lateone.setGravity(Gravity.CENTER);
      latetwo.setGravity(Gravity.CENTER);
      latethree.setGravity(Gravity.CENTER);
      lateone.setPadding(3, 6, 3, 6);
      latetwo.setPadding(3, 6, 3, 6);
      latethree.setPadding(3, 6, 3, 6);
      lateone.setBackgroundResource(R.drawable.left);
      latetwo.setBackgroundResource(R.drawable.middle);
      latethree.setBackgroundResource(R.drawable.right);
      line.setBackgroundColor(getResources().getColor(R.color.blue));
      line1.setBackgroundColor(getResources().getColor(R.color.blue));
      
      //在此布局上添加组件
      this.removeAllViews();
      this.addView(lateone);
      this.addView(line);
      this.addView(latetwo);
      this.addView(line1);
      this.addView(latethree);
      this.invalidate();
      lateone.setSelected(true);
      
      
      //添加监听事件
      lateone.setOnClickListener(new OnClickListener() {
		
		@Override
		public void onClick(View v) {
			// TODO Auto-generated method stub
			if(lateone.isSelected()){
				return ;
			}
			lateone.setSelected(true);
            latetwo.setSelected(false);	
            latethree.setSelected(false);
            if(listener !=null){
            	 listener.setOnsegment(lateone, 0);
            }
		}
	});
      
      latetwo.setOnClickListener(new OnClickListener() {
		
		@Override
		public void onClick(View v) {
			// TODO Auto-generated method stub
			if(latetwo.isSelected()){
				return ;
			}
			lateone.setSelected(false);
            latetwo.setSelected(true);	
            latethree.setSelected(false);
            if(listener !=null){
                listener.setOnsegment(latetwo, 1);
            }
		}
		
	});
      
      latethree.setOnClickListener(new OnClickListener() {
  		
  		@Override
  		public void onClick(View v) {
  			// TODO Auto-generated method stub
  			if(latethree.isSelected()){
  				return ;
  			}
  			lateone.setSelected(false);
              latetwo.setSelected(false);	
              latethree.setSelected(true);
              if(listener !=null){
              	  listener.setOnsegment(latethree, 2);
              }
  		}
  		
  	});
		
	
    }
     
      
      public void setOnsegmentlistenerclicker( Onsegmentlistenerclicker listener){
    	       if(listener != null) 
    	     this.listener = listener;
      }   
	  
     
}
3 实现事件监听的接口设计OnSegmentControclickListener.java    

package com.example.testsegmentcontrol;

import android.view.View;

public interface Onsegmentlistenerclicker {
      
	  public void setOnsegment(View v , int position);
}
4 MainActivity.java显示SegmentControl自定义控件并且实现监听事件作出相应的响应

package com.example.testsegmentcontrol;

import android.support.v7.app.ActionBarActivity;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends Activity {
  
	   private     SegmentView  segmentview;
	
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		segmentview = (SegmentView)findViewById(R.id.showsegmentcontrol);
	   //设置对SegmentControl组件的监听
		segmentview.setOnsegmentlistenerclicker(new Onsegmentlistenerclicker() {
			
			@Override
			public void setOnsegment(View v, int position) {
				// TODO Auto-generated method stub
				     switch (position) {
					case 0:
						  Toast.makeText(getApplicationContext(), "nihao", 0).show();
						break;
	               case 1:
	            	   Toast.makeText(getApplicationContext(), "woshi", 0).show();
						break;
	              case 2:
	            	  Toast.makeText(getApplicationContext(), "haode", 0).show();
	              	break;

			
					}
			}
		});
	   
	
	
	
	
	
	}

	
}
  4 背景选择器(在Drawable文件中)

      changewenzi.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:state_selected="true" android:color="@color/white"/>
	<item android:color="@color/blue"/>

</selector>
  left.xml

   solid  属性  填充的颜色

   corners  属性 角的弧度

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item   android:state_selected="true">
        <shape >
            <solid   android:color="@color/blue" />
            <corners  android:topLeftRadius="3dip" android:bottomLeftRadius="3dip" android:topRightRadius="0dip" android:bottomRightRadius="0dip"/>
     </shape>
    </item>
    <item    >
        <shape   >
        <solid   android:color="@color/white"/>  
        <corners  android:topLeftRadius="3dip" android:bottomLeftRadius="3dip" android:topRightRadius="0dip" android:bottomRightRadius="0dip"/> 
        </shape>
 </item>

</selector>
 middle.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item   android:state_selected="true">
        <shape   >
            <solid    android:color="@color/blue"/>
           <corners android:topLeftRadius="0dip" android:bottomLeftRadius="0dip" android:topRightRadius="0dip" android:bottomRightRadius="0dip"/>
         </shape>
    </item>
    <item >
        <shape   >
         <solid   android:color="@color/white"/>
         <corners  android:topLeftRadius="0dip" android:bottomLeftRadius="0dip" android:topRightRadius="0dip" android:bottomRightRadius="0dip"/>
        </shape>
     </item>
</selector>
rigth.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item   android:state_selected="true">
        <shape >
            <solid  android:color="@color/blue"/>
            <corners android:topLeftRadius="0dip" android:bottomLeftRadius="0dip" android:topRightRadius="3dip" android:bottomRightRadius="3dip"/>
        </shape>
    </item>
 <item    >
     <shape   >
          <solid  android:color="@color/white"/>
          <corners android:topLeftRadius="0dip" android:bottomLeftRadius="0dip" android:topRightRadius="3dip" android:bottomRightRadius="3dip"/>
     </shape>
 </item>
    
    
</selector>

whole.xml

stroke 属性 外围线条的属性(颜色,大小)

solid   属性  填充的颜色

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item   >
         <shape >
             <stroke  android:color="@color/blue" android:width="3dip"/>
             <solid   android:color="@color/white"/>
             <corners android:topLeftRadius="3dip" android:bottomLeftRadius="3dip" android:topRightRadius="3dip" android:bottomRightRadius="3dip"/>
             
         </shape>
    </item>

</selector>
5  activity_main.xml 布局文件

<RelativeLayout 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"
  >
      <com.example.testsegmentcontrol.SegmentView
             android:id="@+id/showsegmentcontrol"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
            android:background="@drawable/whole"
             android:padding="0.5dip"
             android:layout_centerInParent="true"
             >
        </com.example.testsegmentcontrol.SegmentView>
   

</RelativeLayout>
注意 : android :padding="0.5dip"必须写上,否则whole.xml背景选择器物效果没有,因为padding属性指的是组件内的内容距离组件边缘的距离,如果不加,背景选择器无效果。

以上就是程序的主要代码,如果有什么建议可以给我说,欢迎评论,大家共同学习,源代码如下:

http://download.csdn.net/detail/danielntz/9411562




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可自定义样式、功能全面的分段件。项目地址:https://github.com/klongmitre/android-segmented-control-view效果图:如何使用xml中直接创建<org.mitre.ascv.AndroidSegmentedControlView         android:id="@ id/androidSegmentedControlView"         android:layout_width="match_parent"         android:layout_height="wrap_content"         ascv:ascv_defaultSelection="0"         ascv:ascv_unselectedTextColor="@color/test_attr_unselected_text_color"         ascv:ascv_selectedTextColor="@color/test_attr_selected_text_color"         ascv:ascv_selectedColor="@color/test_attr_selected_color"         ascv:ascv_unselectedColor="@color/test_attr_unselected_color"         ascv:ascv_items="@array/three_state_option"/>2. java中添加监听监听item的切换ascv = (AndroidSegmentedControlView)this.findViewById(R.id.androidSegmentedControlView); ascv.setIdentifier("ascv01"); //ascv.setItems(new String[]{"Test1aaaaa", "Test2", "Test3"}, new String[]{"1", "2", "3"}); ascv.setOnSelectionChangedListener(new OnSelectionChangedListener(){     @Override     public void newSelection(String identifier, String value) {//当item切换时触发  Toast.makeText(MainActivity.this, "identifier:" identifier "  value:" value, Toast.LENGTH_SHORT).show();     } });参数identifier是当有多个分段件时,同时使用一个监听时,用于区别是哪个触发了事件。属性说明属性名类型使用说明ascv_unselectedTextColorreference未选中的item的文字颜色ascv_unselectedColorreference未选中的item的背景颜色,不包括边框ascv_selectedColorreference选中的item背景的颜色以及边框的颜色ascv_selectedTextColorreference选中的item的文字颜色ascv_itemsreference件item上显示的文字ascv_valuesreference件item的值,会被传给监听。未设置时,默认使用ascv_items。ascv_equalWidthboolean当item上的文字,即ascv_items设置的文字,长度不一致时,item的宽度是否还等长。ascv_stretchboolean是否被拉伸。即件是否填充整个父容。ascv_defaultSelectioninteger默认哪个item被选中,下标从0开始ascv_identifierstring件的ID
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值