自定义View之仿ios分段选择器

一:效果

1.1 可动态添加或删除tab,更改指定tab的文字。

二:实现思路

  1. 自定义view,实现效果
  2. 动态创建textview,有几个tab创建几个textview
  3. 第一个tab和最后一个tab为圆角矩形,其余的为直角矩形,通过shape文件完成
  4. 默认选中第一个tab选项,更改背景颜色和textview颜色,更改其余所有tab的颜色
  5. 设置点击事件,动态更改每一个tab的颜色

三:代码实现

思路我们已经清晰了,下面按照我们的思路编码就行了,没什么难度,下面我就直接贴出代码了,有需要的同学直接拿去用就好了。

在这里重点说一下每个tab中间的分割线,如果不单独做处理的话,你会发现tab的分割线和边框线宽度不一致,影响整体美观度,是因为第一个tab绘制了一遍分割线,第二个tab又绘制了一遍分割线。

博主的处理方式为:

  1. 为整个自定义view设置一个整体的边框
  2. 每个tab只设置右边的一条边框,最后一个tab不设置边框,采用 <layer-list> 实现

3.1 自定义view代码

package com.zuohp.jstt.widget;

import android.content.Context;
import android.content.res.ColorStateList;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;


import com.zuohp.jstt.R;

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

public class SegmentView extends LinearLayout {
    // 实现不同的按钮状态,不同的颜色
    ColorStateList cs1 = getResources().getColorStateList(R.color.white);
    ColorStateList cs2 = getResources().getColorStateList(R.color.colorPrimaryDark);
    private onSegmentViewClickListener segmentListener;
    //存放textview的集合
    List<TextView> views = new ArrayList<TextView>();

    // 这是代码加载ui必须重写的方法
    public SegmentView(Context context) {
        super(context);
    }
    // 这是在xml布局使用必须重写的方法
    public SegmentView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public SegmentView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    //主要方法
    public void contentView(String[] text,int dp){
        this.removeAllViews();
        this.setBackgroundResource(R.drawable.segment_lin_bg);
        for (int i = 0; i < text.length; i++) {
            final TextView textView = new TextView(getContext());
            textView.setLayoutParams(new LayoutParams(0, LayoutParams.WRAP_CONTENT, 1));
            textView.setText(text[i]);
            textView.setGravity(Gravity.CENTER);
            textView.setPadding(5, 14, 5, 14);
            textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, dp);
            if (i==0){//第一个
                textView.setBackgroundResource(R.drawable.segment_left);
                textView.setSelected(true);
                textView.setTextColor(cs2);
            }else if (i==text.length-1){//最后一个
                textView.setBackgroundResource(R.drawable.segment_right);
                textView.setTextColor(cs1);
            }else {//中间的
                textView.setBackgroundResource(R.drawable.segment_centre);
                textView.setTextColor(cs1);
            }
            //设置id方便在设置点击事件的时候区分是那个view
            textView.setId(i);
            views.add(textView);
            this.addView(textView);
            //设置点击事件
            textView.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    for (TextView view:views) {
                        view.setSelected(false);
                        view.setTextColor(cs1);
                    }
                    views.get(v.getId()).setSelected(true);
                    views.get(v.getId()).setTextColor(cs2);
                    if (segmentListener != null) {
                        segmentListener.onSegmentViewClick(textView, v.getId());
                    }
                }
            });

        }
        this.invalidate();//重新draw()

    }

    /**
     * 设置控件显示的文字
     *
     * @param text
     * @param position
     */
    public void setSegmentText(CharSequence text, int position) {
   }

    // 定义一个接口接收点击事件
    public interface onSegmentViewClickListener {
        public void onSegmentViewClick(View view, int postion);
    }

    public void setOnSegmentViewClickListener(onSegmentViewClickListener segmentListener) {
        this.segmentListener = segmentListener;
    }
}

3.2 shape文件 ---- segment_lin_bg

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <corners android:topLeftRadius="20dp"
        android:topRightRadius="20dp"
        android:bottomRightRadius="20dp"
        android:bottomLeftRadius="20dp"/>
    <padding
        android:right="1dp"
        android:left="1dp"
        android:top="1dp"
        android:bottom="1dp"
        />
    <stroke android:width="1dp" android:color="@color/white" />
</shape>

3.3 shape文件 ---- segment_left

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true">
        <shape>
            <solid android:color="@color/white"/>
            <corners
                android:bottomLeftRadius="20dp"
                android:bottomRightRadius="0dp"
                android:topLeftRadius="20dp"
                android:topRightRadius="0dp" />
        </shape>
    </item>
    <item>
        <layer-list>
            <item>
                <shape>
                    <solid android:color="@color/colorPrimaryDark"  />
                    <corners
                        android:bottomLeftRadius="20dp"
                        android:bottomRightRadius="0dp"
                        android:topLeftRadius="20dp"
                        android:topRightRadius="0dp" />
                </shape>
            </item>
            <item
                android:width="1dp"
                android:gravity="right" >
                <shape>
                    <solid
                        android:color="@color/white"/>
                </shape>
            </item>

        </layer-list>

    </item>
</selector>

3.4 shape文件 ---- segment_right

<?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/white" />
            <corners
                android:bottomLeftRadius="0dp"
                android:bottomRightRadius="20dp"
                android:topLeftRadius="0dp"
                android:topRightRadius="20dp" />
        </shape>
    </item>

    <item>
        <shape>
            <solid android:color="@color/colorPrimaryDark" />
            <corners
                android:bottomLeftRadius="0dp"
                android:bottomRightRadius="20dp"
                android:topLeftRadius="0dp"
                android:topRightRadius="20dp" />
        </shape>
    </item>
</selector>

3.5 shape文件 ---- segment_centre

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true">
        <shape>
            <solid android:color="@color/white"/>
        </shape>
    </item>
    <item>
        <layer-list>
            <item>
                <shape>
                    <solid android:color="@color/colorPrimaryDark"  />
                </shape>
            </item>
            <item
                android:width="1dp"
                android:gravity="right" >
                <shape>
                    <solid
                        android:color="@color/white"/>
                </shape>
            </item>

        </layer-list>

    </item>
</selector>

3.6 xml文件

<android.support.v7.widget.Toolbar
        android:id="@+id/mToolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="?attr/actionBarSize"
        app:contentInsetStart="0dp"
        android:background="@color/colorPrimaryDark">
        <com.zuohp.jstt.widget.SegmentView
            android:id="@+id/segmentview"
            android:layout_width="200dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:orientation="horizontal"
            >

        </com.zuohp.jstt.widget.SegmentView>
    </android.support.v7.widget.Toolbar>

3.7 使用代码

SegmentView segmentView = findViewById(R.id.segmentview);
        segmentView.contentView(new String[]{"TAB1","TAB2","TAB3"},16);
        segmentView.setOnSegmentViewClickListener(new SegmentView.onSegmentViewClickListener() {
            @Override
            public void onSegmentViewClick(View view, int postion) {
                switch (postion){
                    case 0:
                        Toast.makeText(MainActivity.this,"点击了tab1",Toast.LENGTH_SHORT).show();
                        break;
                    case 1:
                        Toast.makeText(MainActivity.this,"点击了tab2",Toast.LENGTH_SHORT).show();
                        break;
                    case 2:
                        Toast.makeText(MainActivity.this,"点击了tab3",Toast.LENGTH_SHORT).show();
                        break;
                }
            }
        });

四:结语

如有更好的方式或者不对的地方,欢迎指出!

祝:工作顺利!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用SwiftUI自定义iOS分段控件可以通过以下步骤实现: 1. 创建一个新的SwiftUI View,命名为SegmentedControl。 2. 在SegmentedControl中定义一个枚举类型,用于表示分段控件中的选项。 3. 在SegmentedControl中定义一个@Binding属性用于绑定选中的选项。 4. 在SegmentedControl中使用ForEach循环遍历所有的选项,并将它们显示在分段控件中。 5. 在ForEach循环中,使用Button显示每一个选项,并在按钮的action中更新选中的选项。 6. 为分段控件添加样式,例如设置选中的选项的背景色和字体颜色等。 下面是一个简单的示例代码: ```swift enum SegmentedOption: String, CaseIterable { case option1 case option2 case option3 } struct SegmentedControl: View { @Binding var selectedOption: SegmentedOption var body: some View { HStack { ForEach(SegmentedOption.allCases, id: \.self) { option in Button(action: { self.selectedOption = option }) { Text(option.rawValue) .foregroundColor(self.selectedOption == option ? .white : .black) .padding(.horizontal, 20) .padding(.vertical, 10) .background(self.selectedOption == option ? Color.blue : Color.gray) .cornerRadius(10) } } } } } ``` 在使用时,只需要将SegmentedControl添加到需要显示的View中,并将选中的选项绑定到某个属性即可。例如: ```swift struct ContentView: View { @State private var selectedOption: SegmentedOption = .option1 var body: some View { VStack { SegmentedControl(selectedOption: $selectedOption) Text("Selected option: \(selectedOption.rawValue)") } } } ``` 这样就可以在界面上显示一个自定义iOS分段控件了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值