Einfache Implementierung von benutzerdefinierten Android-Steuerelementen

Anfang

Vorwort

Ich habe vor kurzem von einem kleinen Unternehmen gekündigt und beschlossen, das zu wiederholen, was ich zuvor gelernt habe. Veröffentlichen Sie also einen Artikel über benutzerdefinierte Steuerelemente, um Ihren Eindruck zu vertiefen, und bereiten Sie sich gleichzeitig auf die zukünftige Jobsuche vor. Fangen wir jetzt ohne Umschweife an.

Einführung in benutzerdefinierte Steuerelemente

Bei der Entwicklung benutzerdefinierter Steuerelemente in Android erben alle Steuerelemente in Android die View-Klasse. Das folgende Bild stellt das Vererbungsbeziehungsdiagramm jedes Steuerelements dar.
Vererbungsdiagramm
Tatsächlich erbt das sogenannte benutzerdefinierte Steuerelement tatsächlich die View-Klasse und schreibt die darin enthaltenen internen Methoden neu. Im Allgemeinen gibt es drei Möglichkeiten, Steuerelemente anzupassen:
1. Ansicht anpassen: Ansicht erben.
2. Basierend auf vorhandenen Komponenten: Erben Sie die abgeleitete Klasse von View.
3. Die Art der Kombination: Das benutzerdefinierte Steuerelement enthält andere Komponenten.

Heute stellen wir die Kombinationsmethode vor, um die benutzerdefinierte Ansicht zu realisieren. Die anderen beiden Methoden werden veröffentlicht, nachdem der Redakteur davon erfahren hat.

üben

Egal wie viel Theorie gesagt wird, es ist nicht so real wie die Praxis.Hier ist eine Konstruktionszeichnung, die aus dem Internet heruntergeladen wurde.

DEMO-Diagramm

analysieren

Wenn wir diese Art von Schnittstelle implementieren wollen, scheint es ziemlich einfach zu sein, und es besteht keine Notwendigkeit, es anzupassen, aber im Vergleich zu einigen Leuten, die faul sein wollen (um der langfristigen Entwicklung willen). Es ist besser, es anzupassen, damit es, wenn wir es in anderen Layoutdateien verwenden müssen, direkt als Steuerelement verwendet werden kann. Ist es bequem? ?
Um es ganz klar auszudrücken, es geht darum, das folgende Bild als Steuerelement anzupassen und es direkt als Steuerelement zu verwenden, wenn es später verwendet wird.

Bildbeschreibung hier einfügen

Die Idee der Umsetzung ist eigentlich ganz einfach: Passen Sie einen kombinierten View an, wickeln Sie ihn horizontal in ein lineares Layout und ordnen Sie ImageView, TextView, TextView und ImageView hintereinander an. Nicht viel Unsinn, mal sehen, wie man es erreicht.

erreichen

1. Benutzerdefiniertes Steuerungslayout definieren (custom_item_view)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

<!--   线性布局水平对齐包裹-->
    <LinearLayout
        android:id="@+id/setting_item"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:background="#ffffff"
        android:padding="5dp"
        android:orientation="horizontal">

        <!--   自定义控件中第一个图片-->
        <ImageView
            android:id="@+id/setting_item_logo"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"/>
        <!--   自定义控件中标题-->
        <TextView
            android:id="@+id/setting_item_title"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_marginLeft="5dp"
            android:gravity="center"
            android:textColor="#000000"
            android:textSize="18sp"/>
        <!--   为了实现,用一个TextView将后边的控件显示在右边
                 也可以用RelativeLayout实现-->
        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"/>
        <!--   自定义控件中概述-->
        <TextView
            android:id="@+id/setting_item_desc"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_marginRight="5dp"
            android:gravity="center"
            android:textColor="#999999"
            android:textSize="15sp"/>
        <!--   自定义控件中第二个图片-->
        <ImageView
            android:id="@+id/setting_item_more"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="5dp"/>
    </LinearLayout>
    <!--   自定义控件中下划线-->
    <View
        android:id="@+id/setting_item_line"
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:background="#888888"/>
</LinearLayout>
2. Erstellen Sie eine neue attrs.XML-Datei, um benutzerdefinierte Steuerelementeigenschaften festzulegen
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="CustomSettingItemView">
<!--        Item标题-->
        <attr name="settingItemTitle" format="string"/>
<!--        Item描述-->
        <attr name="settingItemDesc" format="string"/>
<!--        第一张图片-->
        <attr name="settingLogoSrc" format="reference"/>
<!--        第二张图片-->
        <attr name="settingMoreSrc" format="reference"/>
<!--        下划线显示与否-->
        <attr name="settingItemUnderLineVisibility" format="boolean"/>
    </declare-styleable>
</resources>
3. FrameLayout erben und den Konstruktor überschreiben

Auslesen der Attributparameter in der Layoutdatei (siehe Methode init):
Wird ein benutzerdefinierter Parameter im Layout übergeben, kann dieser aus dem AttributeSet im Konstruktor ausgelesen und auf das Control gesetzt werden.

package com.example.customview_setting_item.customView;

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.LinearLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.example.customview_setting_item.R;

/**
 * Create by 25497 on 2019/10/6
 * The project name is CustomView-setting_item
 * Leo Mark
 *
 * Desc:  自定义控件(继承FrameLayout)
 **/
public class CustomSettingItemView extends FrameLayout {
    
    

    private Context mContext;
    private View mainView;

    private LinearLayout settingItem;
    private ImageView settingItemLogo;//第一张图片
    private ImageView settingItemMore;//第二张图片
    private TextView settingItemTitle;//标题
    private TextView settingItemDesc;//概述
    private View settingItemUnderLine;//下划线

    private String settingItemTitleText;//标题内容
    private String settingItemDescText;//概述内容
    private int settingItemLogoSrc;//第一张图片路径
    private int settingItemMoreSrc;//第二张图片路径
    private boolean settingItemLineVisibility;//下划线显示与否判断

    public String getSettingItemTitleText() {
    
    
        return settingItemTitleText;
    }

    public void setSettingItemTitleText(String settingItemTitleText) {
    
    
        if (settingItemTitleText!=null){
    
    
            this.settingItemTitleText = settingItemTitleText;
            settingItemTitle.setText(settingItemTitleText);//将内容设置进控件中
        }

    }

    public String getSettingItemDescText() {
    
    
        return settingItemDescText;
    }

    public void setSettingItemDescText(String settingItemDescText) {
    
    
        if (settingItemDescText!=null) {
    
    
            this.settingItemDescText = settingItemDescText;
            settingItemDesc.setText(settingItemDescText);//将内容设置进控件中
        }
    }

    public int getSettingItemLogoSrc() {
    
    
        return settingItemLogoSrc;
    }

    public void setSettingItemLogoSrc(int settingItemLogoSrc) {
    
    
        if (settingItemLogoSrc!=10000) {
    
    
            this.settingItemLogoSrc = settingItemLogoSrc;
            settingItemLogo.setImageResource(settingItemLogoSrc);//将图片地址设置进控件中
        }
    }

    public int getSettingItemMoreSrc() {
    
    
        return settingItemMoreSrc;
    }

    public void setSettingItemMoreSrc(int settingItemMoreSrc) {
    
    
        if (settingItemMoreSrc!=10000) {
    
    
            this.settingItemMoreSrc = settingItemMoreSrc;
            settingItemMore.setImageResource(settingItemMoreSrc);//将图片地址设置进控件中
        }
    }

    public boolean getSettingItemLineVisibility() {
    
    
        return settingItemLineVisibility;
    }

    public void setSettingItemLineSize(boolean settingItemLineVisibility) {
    
    
            this.settingItemLineVisibility = settingItemLineVisibility;
            //判断是否显示下划线
            if (settingItemLineVisibility){
    
    
                settingItemUnderLine.setVisibility(VISIBLE);
            }else{
    
    
                settingItemUnderLine.setVisibility(INVISIBLE);
            }
    }

    public CustomSettingItemView(@NonNull Context context) {
    
    
        super(context);
    }

    public CustomSettingItemView(@NonNull Context context, @Nullable AttributeSet attrs) {
    
    
        super(context, attrs);
        init(context,attrs);
    }

    public CustomSettingItemView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    
    
        super(context, attrs, defStyleAttr);
        init(context,attrs);
    }

    public CustomSettingItemView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    
    
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context,attrs);
    }

    /**
     * 定义自定义控件中的属性
     * @param context
     * @param attrs
     */
    private void init(Context context, AttributeSet attrs) {
    
    
        this.mContext=context;
        LayoutInflater inflater= (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mainView=inflater.inflate(R.layout.custom_setting_item_view,this,true);
        initView(mainView);//初始布局中的控件

        TypedArray typedArray=mContext.obtainStyledAttributes(attrs, R.styleable.CustomSettingItemView);
        setSettingItemTitleText(typedArray.getString(R.styleable.CustomSettingItemView_settingItemTitle));
        setSettingItemDescText(typedArray.getString(R.styleable.CustomSettingItemView_settingItemDesc));
        setSettingItemLogoSrc(typedArray.getResourceId(R.styleable.CustomSettingItemView_settingLogoSrc,10000));
        setSettingItemMoreSrc(typedArray.getResourceId(R.styleable.CustomSettingItemView_settingMoreSrc,10000));
        setSettingItemLineSize(typedArray.getBoolean(R.styleable.CustomSettingItemView_settingItemUnderLineVisibility,true));
    }

    /**
     * 初始化控件
     * @param mainView
     */
    private void initView(View mainView) {
    
    
        settingItemTitle=mainView.findViewById(R.id.setting_item_title);
        settingItemDesc=mainView.findViewById(R.id.setting_item_desc);
        settingItemLogo=mainView.findViewById(R.id.setting_item_logo);
        settingItemMore=mainView.findViewById(R.id.setting_item_more);
        settingItemUnderLine=mainView.findViewById(R.id.setting_item_line);
    }
}

4. Ändern Sie die Hauptfunktionslayoutdatei

Erstellen Sie den Hauptfunktionseintrag MainActivity, und verwenden Sie in der Layoutdatei einfach den benutzerdefinierten als Steuerelement oder setzen Sie ihn dynamisch im Code. Ich habe nur zufällig die Bilder gefunden, die ich zuvor verwendet habe, um ihn anzuzeigen.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical">

    <com.example.customview_setting_item.customView.CustomSettingItemView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:settingItemTitle="测试标题1"
        app:settingItemDesc="测试详情1"
        app:settingLogoSrc="@mipmap/soufa"
        app:settingMoreSrc="@mipmap/more"/>
    <com.example.customview_setting_item.customView.CustomSettingItemView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:settingItemTitle="测试标题2"
        app:settingLogoSrc="@mipmap/soufa"
        app:settingMoreSrc="@mipmap/more"/>
    <com.example.customview_setting_item.customView.CustomSettingItemView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:settingItemTitle="测试标题3"
        app:settingItemDesc="测试详情3"
        app:settingLogoSrc="@mipmap/soufa"
        app:settingMoreSrc="@mipmap/more"/>
    <com.example.customview_setting_item.customView.CustomSettingItemView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:settingItemTitle="测试标题4"
        app:settingItemDesc="测试详情4"
        app:settingLogoSrc="@mipmap/soufa"
        app:settingMoreSrc="@mipmap/more"
        app:settingItemUnderLineVisibility="false"/>
    <com.example.customview_setting_item.customView.CustomSettingItemView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        app:settingItemTitle="测试标题5"
        app:settingItemDesc="测试详情5"
        app:settingLogoSrc="@mipmap/soufa"
        app:settingMoreSrc="@mipmap/more"/>
    <com.example.customview_setting_item.customView.CustomSettingItemView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:settingItemTitle="测试标题6"
        app:settingItemDesc="测试详情6"
        app:settingLogoSrc="@mipmap/soufa"/>
    <com.example.customview_setting_item.customView.CustomSettingItemView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:settingItemTitle="测试标题7"
        app:settingItemDesc="测试详情7"
        app:settingLogoSrc="@mipmap/soufa"
        app:settingMoreSrc="@mipmap/more"/>

</LinearLayout>
Rendern nach dem Ausführen auf einer virtuellen Maschine

Verstehe das Bild

Zusammenfassen

Das Obige ist die kombinierte Implementierung von benutzerdefinierten Steuerelementen. In der tatsächlichen Entwicklung ist es definitiv nicht so einfach, aber es ist untrennbar. Solange wir die Denkweise verstehen, müssen wir uns nicht um die unangemessenen Anforderungen des Projekts kümmern Manager. Dies ist natürlich nur eine einfache Umsetzung, wenn Sie mehr Effekte erzielen möchten. Dies kann realisiert werden, indem die Ansicht geerbt und onMeasure, onLayout und onDraw der Komponente durch die erste benutzerdefinierte Ansicht, die zuvor geschrieben wurde, neu geschrieben werden.

Nun, eine der Möglichkeiten, View anzupassen, ist wie folgt: Wenn es Fehler gibt, freue ich mich auf Ihre Kritik und Korrektur. Das Codewort ist nicht einfach, ich hoffe, Sie werden es bookmarken, reposten und mögen.

Acho que você gosta

Origin blog.csdn.net/weixin_43683367/article/details/102332683
Recomendado
Clasificación