自定义视图中子视图的ID在Android中相同 [英] ID of the child views in a custom view are same in Android

查看:56
本文介绍了自定义视图中子视图的ID在Android中相同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义视图 ValueSelectorView ,其中包含两个用于递增和递减值的按钮以及一个用于显示该值的EditText.在我的活动中,我使用了3次此视图.我这里关心的是子视图,它们的 id 在登录日志时总是相同的.因此,结果值不正确.

I have a custom view ValueSelectorView which contains two buttons to increment and decrement value and an EditText to display that value. In my activity, I am using this view three times. My concern here is with the child views that their id is always the same when checked in logs. Due to this, the resultant value comes out to be incorrect.

我查看了StackOverflow,发现其中一些面临相同的问题,他们正试图通过使用 setId 手动更改子视图的ID来解决此问题.尝试使用几种不同的方法夸大子视图,但问题仍然存在

I have looked over on StackOverflow and found out that some of them have faced the same issue and they are trying to solve it by manually altering the id of the child views using setId. Tried inflating the child views using a couple of different methods but the issue still persists

这是我的自定义视图类

package eu.siacs.conversations.ui.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.annotation.RequiresApi;

import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;

public class ValueSelectorView extends RelativeLayout {

    View rootView;
    EditText valueTextView;
    View minusButton;
    View plusButton;

    private int minValue = Integer.MIN_VALUE;
    private int maxValue = Integer.MAX_VALUE;

    public ValueSelectorView(Context context) {
        super(context);
        init(context, null);
    }

    public ValueSelectorView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public ValueSelectorView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public ValueSelectorView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        rootView = LayoutInflater.from(context).inflate(R.layout.value_selector, this, true);
        Log.i(Config.LOGTAG, "****view testr**** id of this view is -->" + getResources().getResourceEntryName(rootView.getId()));
        valueTextView = rootView.findViewById(R.id.valueTextView);

        minusButton = rootView.findViewById(R.id.minusButton);
        plusButton = rootView.findViewById(R.id.plusButton);

        minusButton.setOnClickListener(v -> decrementValue());

        plusButton.setOnClickListener(v -> incrementValue());

        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ValueSelectorView,0,0);
        int defaultVaue = typedArray.getInt(R.styleable.ValueSelectorView_defaultValue,0);
        Log.i(Config.LOGTAG, "****view testr**** id of this TextView is 0 -->" + valueTextView.getId());
//        Log.i(Config.LOGTAG, "****view testr**** id of this Minus Button is 0 -->" + minusButton.getId());
//        Log.i(Config.LOGTAG, "****view testr**** id of this Add Button is 0 -->" + plusButton.getId());
        valueTextView.setText(String.valueOf(defaultVaue));

        typedArray.recycle();
    }

    public void setDefaultValue(int value) {
        valueTextView.setText(String.valueOf(value));
    }

    public int getMinValue() {
        return minValue;
    }

    public void setMinValue(int minValue) {
        this.minValue = minValue;
    }

    public int getMaxValue() {
        return maxValue;
    }

    public void setMaxValue(int maxValue) {
        this.maxValue = maxValue;
    }

    public int getValue() {
        return Integer.valueOf(valueTextView.getText().toString());
    }

    /*public void setValue(int newValue) {
        int value = newValue;
        if(newValue < minValue) {
            value = minValue;
        } else if (newValue > maxValue) {
            value = maxValue;
        }
        Log.i(Config.LOGTAG, "****view testr**** id of this TextView is 1 -->" + valueTextView.getId());
        valueTextView.setText(String.valueOf(value));
    }*/

    @Override
    public void addView(View child, int index, ViewGroup.LayoutParams params) {
        super.addView(child, index, params);
    }

    private void incrementValue() {

        int currentVal = Integer.valueOf(valueTextView.getText().toString());
        if(currentVal < maxValue) {
            Log.i(Config.LOGTAG, "****view testr**** id of this TextView is 2-->" + valueTextView.getId());
            valueTextView.setText(String.valueOf(currentVal + 1));
        }
    }

    private void decrementValue() {
        int currentVal = Integer.valueOf(valueTextView.getText().toString());
        if(currentVal > minValue) {
            Log.i(Config.LOGTAG, "****view testr**** id of this TextView is 3-->" + valueTextView.getId());
            valueTextView.setText(String.valueOf(currentVal - 1));
        }
    }


}

这就是我在活动XML中使用它的方式.

This is how I use it in my activity XML.

<eu.siacs.conversations.ui.widget.ValueSelectorView
                android:id="@+id/value_selector_nights"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="@dimen/margin4"
                app:defaultValue="1"
                android:gravity="center_vertical"/>

<eu.siacs.conversations.ui.widget.ValueSelectorView
                    android:id="@+id/value_selector_adults"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="@dimen/margin4"
                    app:defaultValue="1"
                    android:gravity="center_vertical"/>

<eu.siacs.conversations.ui.widget.ValueSelectorView
                    android:id="@+id/value_selector_children"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    app:defaultValue="0"
                    android:layout_marginTop="@dimen/margin4"
                    android:gravity="center_vertical"/>

下面是日志:

****view testr**** id of this view is -->value_selector_nights
****view testr**** id of this TextView is 0 -->2131297384
****view testr**** id of this view is -->value_selector_adults
****view testr**** id of this TextView is 0 -->2131297384
****view testr**** id of this view is -->value_selector_children
****view testr**** id of this TextView is 0 -->2131297384

我想了解它在内部如何工作,并找到解决方案.谢谢您的时间.

I would like to understand how it works internally and find a solution for the same. Thank you for your time.

推荐答案

对于其他面临相同问题的人.

For others, who are facing the same issue.

我更新的代码是:

package eu.siacs.conversations.ui.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.Log;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;

import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;

public class ValueSelectorView extends RelativeLayout {

    View rootView;
    EditText valueTextView;
    View minusButton;
    View plusButton;
    private int customState;

    private int minValue = Integer.MIN_VALUE;
    private int maxValue = Integer.MAX_VALUE;

    public ValueSelectorView(Context context) {
        super(context);
        init(context, null);
    }

    public ValueSelectorView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public ValueSelectorView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public ValueSelectorView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        rootView = LayoutInflater.from(context).inflate(R.layout.value_selector, this, true);
        Log.i(Config.LOGTAG, "****view testr**** id of this view is -->" + getResources().getResourceEntryName(rootView.getId()));
        valueTextView = rootView.findViewById(R.id.valueTextView);

        minusButton = rootView.findViewById(R.id.minusButton);
        plusButton = rootView.findViewById(R.id.plusButton);

        minusButton.setOnClickListener(v -> decrementValue());

        plusButton.setOnClickListener(v -> incrementValue());

        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ValueSelectorView,0,0);
        int defaultVaue = typedArray.getInt(R.styleable.ValueSelectorView_defaultValue,0);
        Log.i(Config.LOGTAG, "****view testr**** id of this TextView is 0 -->" + valueTextView.getId());
//        Log.i(Config.LOGTAG, "****view testr**** id of this Minus Button is 0 -->" + minusButton.getId());
//        Log.i(Config.LOGTAG, "****view testr**** id of this Add Button is 0 -->" + plusButton.getId());
        valueTextView.setText(String.valueOf(defaultVaue));

        typedArray.recycle();
    }

    public void setDefaultValue(int value) {
        valueTextView.setText(String.valueOf(value));
    }

    public int getMinValue() {
        return minValue;
    }

    public void setMinValue(int minValue) {
        this.minValue = minValue;
    }

    public int getMaxValue() {
        return maxValue;
    }

    public void setMaxValue(int maxValue) {
        this.maxValue = maxValue;
    }

    public int getValue() {
        return Integer.valueOf(valueTextView.getText().toString());
    }

    /*public void setValue(int newValue) {
        int value = newValue;
        if(newValue < minValue) {
            value = minValue;
        } else if (newValue > maxValue) {
            value = maxValue;
        }
        Log.i(Config.LOGTAG, "****view testr**** id of this TextView is 1 -->" + valueTextView.getId());
        valueTextView.setText(String.valueOf(value));
    }*/

    @Override
    public void addView(View child, int index, ViewGroup.LayoutParams params) {
        super.addView(child, index, params);
    }

    private void incrementValue() {

        int currentVal = Integer.valueOf(valueTextView.getText().toString());
        if(currentVal < maxValue) {
            Log.i(Config.LOGTAG, "****view testr**** id of this TextView is 2-->" + valueTextView.getId());
            valueTextView.setText(String.valueOf(currentVal + 1));
        }
    }

    private void decrementValue() {
        int currentVal = Integer.valueOf(valueTextView.getText().toString());
        if(currentVal > minValue) {
            Log.i(Config.LOGTAG, "****view testr**** id of this TextView is 3-->" + valueTextView.getId());
            valueTextView.setText(String.valueOf(currentVal - 1));
        }
    }

    public void setCustomState(int customState) {
        this.customState = customState;
    }

    @Override
    protected Parcelable onSaveInstanceState() {
        Parcelable superState = super.onSaveInstanceState();
        SavedState ss = new SavedState(superState);
        ss.value = valueTextView.getText().toString();
        return ss;
    }

    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        SavedState ss = (SavedState) state;
        super.onRestoreInstanceState(ss.getSuperState());
        valueTextView.setText(ss.value);
    }

    public static class SavedState extends BaseSavedState {
        String value;

        SavedState(Parcelable superState) {
            super(superState);
        }

        public SavedState(Parcel source) {
            super(source);
            value = source.readString();
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            super.writeToParcel(dest, flags);
            dest.writeString(value);
        }

        public static final Parcelable.Creator<SavedState> CREATOR =
                new Parcelable.Creator<SavedState>() {
                    public SavedState createFromParcel(Parcel in) {
                        return new SavedState(in);
                    }

                    public SavedState[] newArray(int size) {
                        return new SavedState[size];
                    }
                };
    }
}

自定义视图中的子视图XML

Child view XML in my custom view

<EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="@dimen/medium_font"
        android:enabled="false"
        android:background="@null"
        android:textColor="#000000"
        android:layout_centerVertical="true"
        android:layout_toRightOf="@id/minusButton"
        android:saveEnabled="false"
        android:id="@+id/valueTextView" />

这篇关于自定义视图中子视图的ID在Android中相同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆