美文网首页
android-横状栏-自定义组合控件小试

android-横状栏-自定义组合控件小试

作者: 史小豪 | 来源:发表于2020-04-18 12:36 被阅读0次

前言

第一次写博客有些紧张,本人是一名大三学生,水平有限,如有错误请指证交流,也欢迎各式的话题讨论。

这是一篇关于自定义控件之组合控件的文章,主要实现了类似主流app上常见的横状栏(菜单列表)的简单组合封装。

贴一个目前项目中正在使用的效果:

Screenshot_20200417_232135_com.example.ctccp_副本.jpg

最终实现了:左图标、左文字、右文字、右图标、右箭头的内容定制,以及下划线、下划区域的定制。

需求:

因为目前的项目,本人负责个人中心的开发,所以难免要用到大量这样的横状栏去表示功能入口。但如果针对每一个横状栏都要重复地去写布局,就会使代码重复性、耦合度太高,也不便于修改。
于是想到自定义控件的方式来实现如上效果。

思路:

重温自定义控件的三种方式:
1.继承View:通过重写ondraw方法等,以绘图的方式自定义View。
2.继承ViewGroup:继承ViewGroup、LinearLayout、FrameLayout等。
3.组合控件:对已有控件进行组合封装,设置属性接口。
本文主要是基于组合控件。

实践:

1.布局编写
基本思路就是编写一个横状栏的布局文件,我们再在后面通过属性接口使用户可以通过属性的设置来选择哪些控件展示、展示的控件展示什么内容。

  <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/item_horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/white"
    android:orientation="vertical">


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:orientation="horizontal"
        android:padding="@dimen/padding_8"
       >

        <ImageView
            android:id="@+id/left_icon"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="@dimen/padding_8"/>

        <TextView
            android:id="@+id/left_text"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center_vertical"
            android:layout_marginLeft="@dimen/padding_8"
            android:textColor="@color/black"
            android:textSize="@dimen/text_size_normal_14" />

        <TextView
            android:id="@+id/right_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="@dimen/margin_10"
            android:textColor="@color/hint_grey"
            android:textSize="@dimen/text_size_normal_14"
            />

        <ImageView
            android:id="@+id/right_icon"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="@dimen/margin_8"
           />
        <ImageView
            android:id="@+id/right_arrow"
            android:layout_width="25dp"
            android:layout_height="30dp"
            android:layout_marginLeft="0dp"
            android:src="@drawable/ic_personal_info_arrow"
            />
    </LinearLayout>
    <View
        android:id="@+id/divide_line_view"
        android:layout_width="match_parent"
        android:layout_height="@dimen/view_size_1dp"
        android:background="@color/background_grey"
        android:visibility="gone" />
    <View
        android:id="@+id/divide_area_view"
        android:layout_width="match_parent"
        android:layout_height="@dimen/height_8"
        android:background="@color/background_grey"
        android:visibility="gone" />
</LinearLayout>

2.资源文件的编写
这里有关dimen尺寸定义以及图标资源文件就不列出了。
2.1色彩定义in colors.xml:

      <color name="white">#FFFFFF</color>
      <color name="black">#000000</color>
      <color name="hint_grey">#b7b7b7</color>
      <color name="background_grey">#F6F6F6</color>

2.2属性定义in attrs.xml:

一般属性的类型有下面这九种:

foromat 解释
color 颜色值
boolean 布尔值
dimesion 尺寸值
float 浮点值
integer 整型值
string 字符串
fraction 百分数
enum 枚举值
reference 引用资源文件

在<declare-styleable name="ItemHorizontal"> 中给自己定义的横状栏起一个名字,这个名字用来在自定义控件中获取相关属性。
<attr name="left_text" format="string"/> 自定义所需要的属性名称,以及这个属性的类型。

<declare-styleable name="ItemHorizontal">
        <attr name="left_text" format="string" />
        <attr name="left_icon" format="reference" />
        <attr name="right_text" format="string" />
        <attr name="right_icon" format="reference" />
        <attr name="is_show_right_icon" format="boolean" />
        <attr name="is_show_left_icon" format="boolean" />
        <attr name="is_show_right_arrow" format="boolean" />
        <attr name="divide_line_style" format="integer" />
</declare-styleable>

注:styleable标签可以不写。去除styleable标签后在第3步的typedArray获取属性时传入对应常量即可。

3.继承ViewGroup子类
实际上这就是我们前面提到的三种自定义控件方式中的第二种。

package com.example.personalcenter.ui.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;

import com.example.personalcenter.R;


public class ItemHorizontal extends FrameLayout {
    private Context mContext;
    private View mView;
    private TextView leftTv;
    private TextView rightTv;
    private ImageView leftImageView;
    private ImageView rightImageView;
    private ImageView rightArrow;

    public static final int NO_LINE = 0;
    public static final int DIVIDE_LINE = 1;
    public static final int DIVIDE_AREA = 2;

    private String leftText;
    private String rightText;
    boolean isShowLeftIcon;
    boolean isShowRightIcon;
    boolean isShowRightArrow;
    private int divideLineStyle = NO_LINE;

    public String getLeftText() {
        return leftText;
    }

    public void setLeftImageView(boolean isLeftIconShow, int iconImgId) {
        if (isLeftIconShow) {
            if (iconImgId != 9102) {
                leftImageView.setImageResource(iconImgId);
            }
        } else {
            leftImageView.setVisibility(GONE);
        }
    }

    public void  setRightImageView(boolean isRightIconShow, int iconImgId) {
        if (isRightIconShow) {
            if (iconImgId != 9102) {
                rightImageView.setImageResource(iconImgId);
            }
        } else {
            rightImageView.setVisibility(GONE);
        }
    }

    public void  setRightArrowView(boolean isRightArrowShow) {
        if (!isRightArrowShow) {
            rightArrow.setVisibility(INVISIBLE);
        }
    }

    public void setLeftText(String leftText) {
        if (leftText != null) {
            this.leftText = leftText;
            leftTv.setText(leftText);
        }
    }

    public String getRightText() {
        return rightText;
    }

    public void setRightText(String rightText) {
        if (rightText != null) {
            this.rightText = rightText;
            rightTv.setText(rightText);
        }
    }



    public void setDivideLineStyle(int divideLineLineStyle) {
        View lineView = findViewById(R.id.divide_line_view);
        View areaView = findViewById(R.id.divide_area_view);
        if(divideLineLineStyle==DIVIDE_LINE){
            lineView.setVisibility(VISIBLE);
        }
        else if (divideLineLineStyle == DIVIDE_AREA ) {
            areaView.setVisibility(VISIBLE);
        }
    }

    public ItemHorizontal(Context context, AttributeSet attributeSet) {
        super(context, attributeSet);
        init(context, attributeSet);

    }

    public void init(Context context, AttributeSet attributeSet) {
        mContext = context;
        LayoutInflater.from(context).inflate(R.layout.item_horizontal, this);

        leftTv = (TextView) findViewById(R.id.left_text);
        rightTv = (TextView) findViewById(R.id.right_text);
        leftImageView = (ImageView) findViewById(R.id.left_icon);
        rightImageView = (ImageView) findViewById(R.id.right_icon);
        rightArrow=(ImageView)findViewById(R.id.right_arrow);

        TypedArray typedArray = context.obtainStyledAttributes(attributeSet, R.styleable.ItemHorizontal);

        isShowLeftIcon = typedArray.getBoolean(R.styleable.ItemHorizontal_is_show_left_icon, false);
        isShowRightIcon = typedArray.getBoolean(R.styleable.ItemHorizontal_is_show_right_icon, false);
        isShowRightArrow= typedArray.getBoolean(R.styleable.ItemHorizontal_is_show_right_arrow, true);
        divideLineStyle = typedArray.getInt(R.styleable.ItemHorizontal_divide_line_style, NO_LINE);

        setLeftImageView(isShowLeftIcon, typedArray.getResourceId(R.styleable.ItemHorizontal_left_icon, 9102));
        setRightImageView(isShowRightIcon,typedArray.getResourceId(R.styleable.ItemHorizontal_right_icon, 9102));
        setRightArrowView(isShowRightArrow);
        setLeftText(typedArray.getString(R.styleable.ItemHorizontal_left_text));
        setRightText(typedArray.getString(R.styleable.ItemHorizontal_right_text));
        setDivideLineStyle(divideLineStyle);

        typedArray.recycle();//注意回收
    }
}

最终使用

 <com.example.personalcenter.ui.widget.ItemHorizontal
                android:id="@+id/ih_settings_account"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:right_text="@string/settings_account_safe"
                app:is_show_right_icon="true"
                app:right_icon="@drawable/ic_settings_safe"
                app:left_text="@string/settings_account"
                app:divide_line_style="1"/>

这样就可以达到最开始那张图的效果啦,具体的样式变化通过属性设置就可以达到定制的效果。
至此,一个基本的自定义组合控件流程就宣告完成。

拓展:

但在这个流程中,相信还可能会出现不少疑问:
1.AttributeSet与TypedArray间的联系?
2.typedeArray是什么?为什么要使用TypedArray

如果理解了这些,那相信以后再遇到自定义组合控件的开发任务就会驾轻就熟啦。
这些内容在鸿洋大神的这篇博客中已经讲的很清楚,这里就不再赘述了。想要学习的朋友点击下方链接即可。
[鸿洋大神的博客]https://blog.csdn.net/lmj623565791/article/details/45022631/

后记

唔,一直有写博客的想法,但是始终因为各种各样的原因而一再推迟。终于,在这个安静的夜晚,我决定使用简书来记录我的日常感悟与开发心得。

不知怎得,突然就想起《邪不压正》里这两人的对话:“正经人谁写日记啊?”,“你写日记吗?”

image

相关文章

  • android-横状栏-自定义组合控件小试

    前言 第一次写博客有些紧张,本人是一名大三学生,水平有限,如有错误请指证交流,也欢迎各式的话题讨论。 这是一篇关于...

  • Android面试复习-View

    自定义控件 1.组合控件。这种自定义控件不需要我们自己绘制,而是使用原生控件组合成新控件,如标题栏。 2.继承原有...

  • 自定义view

    一、自定义view实现方式 二、组合控件 将系统原有的控件进行组合,构成一个新的控件。 定义标题栏的布局文件cus...

  • Android入门06 -- 自定义控件

    自定义组合控件 将几个子控件组合在一起,形成一个可复用的新的组合控件,自定义组合控件一般继承自RelativeLa...

  • 【Android】自定义控件

    Android自定义控件可以有三种实现方式 组合原生控件自己绘制控件继承原生控件 1 组合原生控件 1.1 组合原...

  • android2019-01-03

    1.View的绘制流程自定义控件:1、组合控件。这种自定义控件不需要我们自己绘制,而是使用原生控件组合成的新控件。...

  • 11-自定义组合控件以及使用

    一、自定义组合控件介绍 开发中,为了使用的方便,经常把一些控件组合成一个控件,那样就成为了我们的自定义组合控件,严...

  • Android组合控件详解 & 自定义属性

    组合控件详解 & 自定义属性 摘录来源:极客学院WiKi 组合控件是自定义控件的一种,只不过它是由其他几个原生控件...

  • 组合控件2——海贼王选项菜单

    之前的自定义控件——初识自定义控件,我们了解到了自定义控件分为三种,自制控件,组合控件,拓展控件。而我们在自制控件...

  • 自制控件3——仿qq侧滑删除

    在自定义控件——初识自定义控件里面,我们已经对自定义控件进行描述和分类。其分类分别是 自制控件 组合控件 拓展控件...

网友评论

      本文标题:android-横状栏-自定义组合控件小试

      本文链接:https://www.haomeiwen.com/subject/slrpvhtx.html