高仿QQ顶部控件之IOS SegmentView

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


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

<?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

<?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>

 

<?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。

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文件中的引用:

<?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

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上就简单多了。期待大家一起交流学习吧。

时间: 2024-10-06 23:02:52

高仿QQ顶部控件之IOS SegmentView的相关文章

【Android】史上最简单,一步集成侧滑(删除)菜单,高仿QQ、IOS

本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 转载请标明出处: http://blog.csdn.net/zxt0601/article/details/53157090 本文出自:[张旭童的博客](http://blog.csdn.net/zxt0601) 代码传送门:喜欢的话,随手点个star.多谢 https://github.com/mcxtzhang/SwipeDelMenuLayout 重要的话 开头说,not for the RecyclerView or L

史上最简单,一步集成侧滑(删除)菜单,高仿QQ、IOS。

重要的话 开头说,not for the RecyclerView or ListView, for the Any ViewGroup. 本控件不依赖任何父布局,不是针对 RecyclerView.ListView,而是任意的ViewGroup里的childView都可以使用侧滑(删除)菜单.支持任意ViewGroup.0耦合.史上最简单. 概述 本控件从撸出来在项目使用至今已经过去7个月,距离第一次将它push至github上,也已经2月+.(之前,我发表过一篇文章.传送门:http://b

高仿QQ即时聊天软件开发系列之三登录窗口用户选择下拉框

上一篇高仿QQ即时聊天软件开发系列之二登录窗口界面写了一个大概的布局和原理 这一篇详细说下拉框的实现原理 先上最终效果图 一开始其实只是想给下拉框加一个placeholder效果,让下拉框在未选择未输入时显示一个提示字符串.由于Background对ComboBox无效,所以直接通过Background来实现是不行了.需要重新写ComboBox的模板,也就是Template,自定义一个模板来实现这个结果.又看了一下QQ的下拉框,这玩意不自定义也难以实现,所以就干脆自定义了. 先上代码,先是Com

高仿QQ即时聊天软件开发系列之二登录窗口界面

继上一篇高仿QQ即时聊天软件开发系列之一开端之后,开始做登录窗口 废话不多说,先看效果,只有界面 可能还有一些细节地方没有做,例如那个LOGO嘛,不要在意这些细节 GIF虽短,可是这做起来真难,好吧因为我没玩过WPF所以难,因为感觉做出来之后也就那样 整体布局 整体是上下分,下面是左中右分 1 <Grid> 2 <Grid.RowDefinitions> 3 <RowDefinition Height="27"><!--用于放窗口右上角关闭.最

高仿QQ即时聊天软件开发系列之一开端

前段时间在园子里看到一个大神做了一个GG2014IM软件,仿QQ的,那感觉···,赶快下载源码过来试试,还真能直接跑起来,效果也不错.但一看源码,全都给封装到了ESFramework里面了,音视频那部分的源码也给封装到OMCS里面了,这两家伙都是收费的Orz,还能不能好好的看看源码L 大概看了一下GG(为什么每次念这个词都有种怪怪的感觉)的源码,突然想自己也来弄个高仿QQ的软件,平时时间也比较多,就当锻炼吧.别人GG都有个名字,那我也起个名字吧,就叫CC吧 决定了就开始安排 第一个问题,界面框架

Android高仿QQ消息滑动删除(附源码)

大家都应该使用过QQ吧,他的消息中可以滑动删除功能,我觉得比较有意思,所以模仿写了一个,并且修改了其滑动算法.我先贴几个简单示范图吧 其实主要用的是算法以及对ListView的把控. 一下是适配器的类 ? 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

WinForm 仿360界面控件

因为经常要做一些1.2千行的小工具,WinForm自带的TabCtrl又不美观,所以想做成360的样子,在网上找来找去,都只有散乱的代码,没有可以通用的结构,所以自己写了一个简易的通用控件. 控件主要功能 添加按钮和对应的Userctrl页面,或者相应的Action函数:整个控件是透明背景,窗体的背景将被作为整体背景,即支持类似换肤功能:可自定义按钮的遮罩函数. 支持Userctrl页面切换 支持Action(无参数无返回值)委托 主要类型实现 切换按钮派生自RatioButton,因为已经实现

高仿QQ头像截取升级版

观看此篇文章前,请先阅读上篇文章:高仿QQ头像截取: 本篇之所以为升级版,是在截取头像界面添加了与qq类似的阴影层(裁剪区域以外的部分),且看效果图:   为了适应大家不同需求,这次打了两个包,及上图中一个方形的头像截取demo和一个圆形的: 原理: 方形: 如图:底层即图片层,在上层的画布中,先将裁剪区四周根据裁剪区大小画上阴影,然后在画上裁剪区的白色边框(空心):如下图 主要代码如下: @Override protected void onDraw(Canvas canvas) { supe

高仿QQ的个性名片

效果图 中间的圆形头像和光环波形讲解请看:http://blog.csdn.net/cj_286/article/details/52839036 周围的气泡布局,因为布局RatioLayout是继承自ViewGroup,所以布局layout就可以根据自己的需求来布局其子view,view.layout(int l,int t,int r,int b);用于布局子view在父ViewGroup中的位置(相对于父容器),所以在RatioLayout中计算所有子view的left,top,right