1. 分段控制(SegmentView)
首先我们先看看什么是SegmentView的效果,如下:
分段控制这个View控件是ios7的分段控制,和QQ消息页面顶部的效果一样,android没有这个控件,不过实现起来也比较简单,下面来实现这个样式,实现的样式最终效果如下:
2. SegmentView自定义实现的逻辑过程:
(1)首先我们要定义文字的颜色,文字是交给TextView显示的,当TextView选中和没有选中两者颜色是不一样的,我们在res/color下:
新建segment_text_color_selector.xml文件:
1 <?xml version="1.0" encoding="utf-8"?> 2 <selector 3 xmlns:android="http://schemas.android.com/apk/res/android"> 4 5 <item 6 android:state_selected="true" 7 android:color="#ffffff"> 8 </item> 9 10 <item 11 android:color="#288455"> 12 </item> 13 14 </selector>
(2)然后在res/drawable下新建segment_left_background.xml和segment_right_background.xml
这两个都是Segment-消息 和 Segment-电话 选中和没有选中两种状态对应的不同背景填充
segment_left_background.xml:
1 <?xml version="1.0" encoding="utf-8"?> 2 <selector 3 xmlns:android="http://schemas.android.com/apk/res/android"> 4 5 <item android:state_selected="true"> 6 <shape> 7 <solid android:color="#00c17c" /> 8 9 <corners 10 android:bottomLeftRadius="15dp" 11 android:bottomRightRadius="0dp" 12 android:topLeftRadius="15dp" 13 android:topRightRadius="0dp" /> 14 </shape> 15 </item> 16 17 <item> 18 <shape> 19 <stroke android:width="1dp" android:color="#00c17c" /> 20 <solid android:color="#ffffff" /> 21 <corners android:bottomLeftRadius="15dp" 22 android:bottomRightRadius="0dp" 23 android:topLeftRadius="15dp" 24 android:topRightRadius="0dp" /> 25 </shape> 26 </item> 27 28 </selector>
segment_right_background.xml:
1 <?xml version="1.0" encoding="utf-8"?> 2 <selector xmlns:android="http://schemas.android.com/apk/res/android"> 3 4 <item android:state_selected="true"> 5 <shape> 6 <solid android:color="#00c17c" /> 7 8 <corners 9 android:bottomLeftRadius="0dp" 10 android:bottomRightRadius="15dp" 11 android:topLeftRadius="0dp" 12 android:topRightRadius="15dp" /> 13 </shape> 14 </item> 15 16 <item> 17 <shape> 18 <stroke android:width="1dp" android:color="#00c17c" /> 19 <solid android:color="#ffffff" /> 20 <corners 21 android:bottomLeftRadius="0dp" 22 android:bottomRightRadius="15dp" 23 android:topLeftRadius="0dp" 24 android:topRightRadius="15dp" /> 25 </shape> 26 </item> 27 28 </selector>
(3)Ok,上面资源文件都定义好了,接下来我们就可以自定义SegmentView,由于使用到了weight属性,我们让SegmentView继承自LinearLayout,使用两个TextView,如下:
1 package com.himi.segmentviewdemo; 2 3 import android.content.Context; 4 import android.content.res.ColorStateList; 5 import android.util.AttributeSet; 6 import android.util.TypedValue; 7 import android.view.Gravity; 8 import android.view.View; 9 import android.widget.LinearLayout; 10 import android.widget.TextView; 11 12 public class SegmentView extends LinearLayout { 13 private TextView leftTextView; 14 private TextView rightTextView; 15 private onSegmentViewClickListener segmentListener; 16 17 // 这是代码加载ui必须重写的方法 18 public SegmentView(Context context) { 19 super(context); 20 initView(); 21 } 22 23 // 这是在xml布局使用必须重写的方法 24 public SegmentView(Context context, AttributeSet attrs) { 25 super(context, attrs); 26 initView(); 27 } 28 29 private void initView() { 30 leftTextView = new TextView(getContext()); 31 rightTextView = new TextView(getContext()); 32 33 // 设置textview的布局宽高并设置为weight属性都为1 34 leftTextView.setLayoutParams(new LayoutParams(0, LayoutParams.WRAP_CONTENT, 1)); 35 rightTextView.setLayoutParams(new LayoutParams(0, LayoutParams.WRAP_CONTENT, 1)); 36 37 // 初始化的默认文字 38 leftTextView.setText("消息"); 39 rightTextView.setText("电话"); 40 41 // 实现不同的按钮状态,不同的颜色 42 ColorStateList csl = getResources().getColorStateList(R.color.segment_text_color_selector); 43 leftTextView.setTextColor(csl); 44 rightTextView.setTextColor(csl); 45 46 // 设置textview的内容位置居中 47 leftTextView.setGravity(Gravity.CENTER); 48 rightTextView.setGravity(Gravity.CENTER); 49 50 // 设置textview的内边距 51 leftTextView.setPadding(5, 6, 5, 6); 52 rightTextView.setPadding(5, 6, 5, 6); 53 54 // 设置文字大小 55 setSegmentTextSize(16); 56 57 // 设置背景资源 58 leftTextView.setBackgroundResource(R.drawable.segment_left_background); 59 rightTextView.setBackgroundResource(R.drawable.segment_right_background); 60 61 // 默认左侧textview为选中状态 62 leftTextView.setSelected(true); 63 64 // 加入textview 65 this.removeAllViews(); 66 this.addView(leftTextView); 67 this.addView(rightTextView); 68 this.invalidate();//重新draw() 69 70 leftTextView.setOnClickListener(new OnClickListener() { 71 @Override 72 public void onClick(View v) { 73 if (leftTextView.isSelected()) { 74 return; 75 } 76 leftTextView.setSelected(true); 77 rightTextView.setSelected(false); 78 if (segmentListener != null) { 79 segmentListener.onSegmentViewClick(leftTextView, 0); 80 } 81 } 82 }); 83 84 rightTextView.setOnClickListener(new OnClickListener() { 85 @Override 86 public void onClick(View v) { 87 if (rightTextView.isSelected()) { 88 return; 89 } 90 rightTextView.setSelected(true); 91 leftTextView.setSelected(false); 92 if (segmentListener != null) { 93 segmentListener.onSegmentViewClick(rightTextView, 1); 94 } 95 } 96 }); 97 98 } 99 100 /** 101 * 设置字体大小 102 * 103 * @param dp 104 */ 105 private void setSegmentTextSize(int dp) { 106 leftTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, dp); 107 rightTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, dp); 108 } 109 110 /** 111 * 手动设置选中的状态 112 * 113 * @param i 114 */ 115 public void setSelect(int i) { 116 if (i == 0) { 117 leftTextView.setSelected(true); 118 rightTextView.setSelected(false); 119 } else { 120 leftTextView.setSelected(false); 121 rightTextView.setSelected(true); 122 } 123 } 124 125 /** 126 * 设置控件显示的文字 127 * 128 * @param text 129 * @param position 130 */ 131 public void setSegmentText(CharSequence text, int position) { 132 if (position == 0) { 133 leftTextView.setText(text); 134 } 135 if (position == 1) { 136 rightTextView.setText(text); 137 } 138 } 139 140 // 定义一个接口接收点击事件 141 public interface onSegmentViewClickListener { 142 public void onSegmentViewClick(View view, int postion); 143 } 144 145 public void setOnSegmentViewClickListener(onSegmentViewClickListener segmentListener) { 146 this.segmentListener = segmentListener; 147 } 148 }
(4)上面定义好了SegmentView,接下来去xml布局直接使用就可以了,如下:
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:paddingBottom="@dimen/activity_vertical_margin" 6 android:paddingLeft="@dimen/activity_horizontal_margin" 7 android:paddingRight="@dimen/activity_horizontal_margin" 8 android:paddingTop="@dimen/activity_vertical_margin" 9 tools:context="com.himi.segmentviewdemo.MainActivity" > 10 11 <com.himi.segmentviewdemo.SegmentView 12 android:id="@+id/segmentview" 13 android:layout_width="wrap_content" 14 android:layout_height="wrap_content" 15 android:layout_centerHorizontal="true" > 16 </com.himi.segmentviewdemo.SegmentView> 17 18 </RelativeLayout>
(5)来到MainActivity,设置点击事件,事件可以切换fragment等等
1 package com.himi.segmentviewdemo; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.view.View; 6 import android.widget.Toast; 7 8 public class MainActivity extends Activity { 9 10 private SegmentView mSegmentView; 11 12 @Override 13 protected void onCreate(Bundle savedInstanceState) { 14 super.onCreate(savedInstanceState); 15 setContentView(R.layout.activity_main); 16 17 mSegmentView = (SegmentView) findViewById(R.id.segmentview); 18 mSegmentView.setOnSegmentViewClickListener(new SegmentView.onSegmentViewClickListener() { 19 @Override 20 public void onSegmentViewClick(View view, int postion) { 21 switch (postion) { 22 case 0: 23 Toast.makeText(MainActivity.this, "点击了消息" + postion, 24 Toast.LENGTH_SHORT).show(); 25 break; 26 case 1: 27 Toast.makeText(MainActivity.this, "点击了电话" + postion, 28 Toast.LENGTH_SHORT).show(); 29 break; 30 default: 31 break; 32 } 33 } 34 }); 35 } 36 37 }
部署程序到手机上,如下: