当你的才华还撑不起你的梦想时,你只能一直前进!

高仿QQ顶部控件之IOS SegmentView

经常会看到QQ上面有一个 消息和电话 的顶部面板,这个空间是IOS7的分段控制,android中没有这个控件,
今天在威哥的微信公众号中成功gank到这个自定义控件的实现,下面跟着尝试一波。


首先是定义文字的颜色,在res/color下新建segment_text_color_selector.xml文件

 

1
2
3
4
5
6
7
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="#2ccbf2" android:state_selected="true"/>
    <item android:color="#a7a7a7" android:state_selected="false"/>
 
 
</selector>

  

然后在res/drawable下新建segment_left_background.xml和segment_right_background.xml

 

1
2
3
4
5
6
7
8
9
10
11
<?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="#cfcece"/>
            <corners android:bottomLeftRadius="5dp" android:topLeftRadius="5dp"
                     android:bottomRightRadius="0dp" android:topRightRadius="0dp"/>
        </shape>
    </item>
</selector>

 

 

1
2
3
4
5
6
7
8
9
10
11
<?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="#cfcece"/>
            <corners android:bottomLeftRadius="0dp" android:topLeftRadius="0dp"
                     android:bottomRightRadius="5dp" android:topRightRadius="5dp"/>
        </shape>
    </item>
</selector>

  

 


Ok,资源文件已备好,下面开始自定义segmentView,由于要用到weight属性,我们继承LinearLayout,使用两个textview。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
package com.example.nanchen.segmentviewdemo;
 
import android.content.Context;
import android.content.res.ColorStateList;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
 
/**
 * 自定义SegmentView 使用两个TextView
 * Created by 南尘 on 2016/7/11.
 */
public class SegmentView extends LinearLayout {
    private TextView tv_left;
    private TextView tv_right;
    private onSegmentViewClickListener segmentViewClickListener;
 
    /**
     * 这是代码加载UI必须重写的方法
     * @param context
     */
    public SegmentView(Context context) {
        super(context);
        initView();
    }
 
    /**
     * 这是在xml布局使用必须重写的方法
     * @param context
     * @param attrs
     */
    public SegmentView(Context context, AttributeSet attrs){
        super(context,attrs);
        initView();
 
    }
    private void initView() {
        tv_left = new TextView(getContext());
        tv_right = new TextView(getContext());
 
        //设置TextView的布局宽高并设置weight属性都为1
        tv_left.setLayoutParams(new LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT,1));;
        tv_right.setLayoutParams(new LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT,1));;
 
        //初始化默认文字
        tv_left.setText("消息");
        tv_right.setText("电话");
 
        //实现不同的按钮状态,不同的颜色
        ColorStateList csl = getResources().getColorStateList(R.color.segment_text_color_selector);
        tv_left.setTextColor(csl);
        tv_right.setTextColor(csl);
 
        //设置内容居中
        tv_left.setGravity(Gravity.CENTER);
        tv_right.setGravity(Gravity.CENTER);
 
        //设置TextView的内边距
        tv_left.setPadding(5,6,5,6);
        tv_right.setPadding(5,6,5,6);
 
        //设置文字大小
        setSegmentTextSize(14);
 
        //设置背景资源
        tv_left.setBackgroundResource(R.drawable.segment_left_background);
        tv_right.setBackgroundResource(R.drawable.segment_right_background);
 
        //默认左侧为选中状态
        tv_left.setSelected(true);
 
        //加入TextView
        this.removeAllViews();
        this.addView(tv_left);
        this.addView(tv_right);
        this.invalidate();
 
        tv_left.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (tv_left.isSelected()){
                    return;
                }
                tv_left.setSelected(true);
                tv_right.setSelected(false);
                if(segmentViewClickListener!=null){
                    segmentViewClickListener.onSegmentViewClick(tv_left,0);
                }
            }
        });
        tv_right.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (tv_right.isSelected()){
                    return;
                }
                tv_left.setSelected(false);
                tv_right.setSelected(true);
                if(segmentViewClickListener!=null){
                    segmentViewClickListener.onSegmentViewClick(tv_right,1);
                }
            }
        });
    }
 
    /**
     * 设置字体大小
     * @param dp
     */
    private void setSegmentTextSize(int dp){
        tv_left.setTextSize(TypedValue.COMPLEX_UNIT_DIP,dp);
        tv_right.setTextSize(TypedValue.COMPLEX_UNIT_DIP,dp);
    }
 
 
    /**
     * 定义一个接口用于接收点击事件
     */
    public interface onSegmentViewClickListener{
        public void onSegmentViewClick(View view,int position);
    }
 
    /**
     * 手动设置选中的状态
     *
     * @param i
     */
    public void setSelect(int i) {
        if (i == 0) {
            tv_left.setSelected(true);
            tv_right.setSelected(false);
        } else {
            tv_left.setSelected(false);
            tv_right.setSelected(true);
        }
    }
 
    public void setOnSegmentViewClickListener(
            onSegmentViewClickListener segmentViewClickListener) {
        this.segmentViewClickListener = segmentViewClickListener;
    }
 
 
    /**
     * 设置控件显示的文字
     *
     * @param text
     * @param position
     */
    public void setSegmentText(CharSequence text, int position) {
        if (position == 0) {
            tv_left.setText(text);
        }
        if (position == 1) {
            tv_right.setText(text);
        }
    }
 
 
}

  

 

在XML文件中的引用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="utf-8"?>
<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="wrap_content"
    android:background="#03fbc5"
    tools:context="com.example.nanchen.segmentviewdemo.MainActivity">
 
 
    <com.example.nanchen.segmentviewdemo.SegmentView
        android:orientation="horizontal"
        android:id="@+id/main_segment"
        android:layout_centerInParent="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
 
    </com.example.nanchen.segmentviewdemo.SegmentView>
</RelativeLayout>

  

最后是我们的Activity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.example.nanchen.segmentviewdemo;
 
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Toast;
 
public class MainActivity extends AppCompatActivity {
 
    private SegmentView segmentView;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        segmentView = (SegmentView) findViewById(R.id.main_segment);
 
        segmentView.setOnSegmentViewClickListener(new SegmentView.onSegmentViewClickListener() {
            @Override
            public void onSegmentViewClick(View view, int position) {
                switch (position){
                    case 0:
                        Toast.makeText(MainActivity.this, "点击了消息"+position,Toast.LENGTH_SHORT).show();
                        break;
                    case 1:
                        Toast.makeText(MainActivity.this, "点击了电话"+position,Toast.LENGTH_SHORT).show();
                        break;
                    default:
                        break;
                }
            }
        });
    }
}

  

其实这些东西都只是为了重温自定义View,理清其中必不可少的步骤,自定义View上就简单多了。期待大家一起交流学习吧。

posted @   南尘  阅读(1913)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述

写不完的矫情,做不完的开源

点击进入我的GitHub页
南 尘
主 页
优美钢琴曲合集-南尘.mp3                    感谢您阅读我的博客,如果您现在工作、学习累了或者疲惫了,不妨聆听一下音乐,它能够减轻你的疲劳,还能够带给您一种舒适愉悦的心情。(样式取自博客园-欲泪成雪)
点击右上角即可分享
微信分享提示