Данные выбора номера не отображаются правильно Android

Привет, ребята, я столкнулся с проблемой выбора номера. У меня есть строка, которая должна отображаться как

но при выборе второй опции 'меню' с помощью кнопки выбора и повторного открытия диалогового окна, содержащего средство выбора номера, данные отображаются примерно так

Здесь видно, что меню 1 отображается как в меню параметров выбора номера, так и в верхнем, и в среднем. Но при прокрутке отображаются правильные данные. Код выглядит следующим образом

Основная деятельность

package com.example.anakumar6.numberpickerexample;

import android.app.Dialog;
import android.graphics.Color;
import android.os.Bundle;
import android.app.Activity;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.TextView;
import android.widget.NumberPicker;


public class MainActivity extends AppCompatActivity {
    int index =0;
    TextView tv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //Get the widgets reference from XML layout
        tv = (TextView) findViewById(R.id.tv);
        tv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                showDialog(MainActivity.this);
            }
        });

    }

    public void showDialog(Activity activity){
        final Dialog dialog = new Dialog(activity);
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setCancelable(false);
        dialog.setContentView(R.layout.dialog);

        final NumberPicker np = (NumberPicker) dialog.findViewById(R.id.np);

        //Set TextView text color
        tv.setTextColor(Color.parseColor("#FF2C834F"));

        //Initializing a new string array with elements
        final String[] values= {"Menu 1", "Menu", "Menu 2"};
//        modifyDataForNumberPicker(values);


        //Populate NumberPicker values from String array values
        //Set the minimum value of NumberPicker
        np.setMinValue(0); //from array first value
        //Specify the maximum value/number of NumberPicker
        np.setMaxValue(values.length-1); //to array last value

        //Specify the NumberPicker data source as array elements
        np.setDisplayedValues(values);
        np.setValue(index);

        //Gets whether the selector wheel wraps when reaching the min/max value.
        np.setWrapSelectorWheel(true);

        //Set a value change listener for NumberPicker
        np.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
            @Override
            public void onValueChange(NumberPicker picker, int oldVal, int newVal){
                //Display the newly selected value from picker
                tv.setText("Selected value : " + values[newVal]);
                index = newVal;
            }
        });

        Button dialogButton = (Button) dialog.findViewById(R.id.btnClick);
        dialogButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dialog.dismiss();
            }
        });

        dialog.show();

    }

}

activity_main.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:id="@+id/rl"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    android:padding="16dp"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Select a number..."
        android:textSize="25dp" />
</RelativeLayout>

dialog.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#ffffffff"
    >

    <NumberPicker
        android:id="@+id/np"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_below="@id/tv"
        android:layout_weight="1"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/btnClick"
        android:text="select"/>
</LinearLayout>

Я думаю, что это вопрос выбора номера Android. Пожалуйста, помогите мне решить эту проблему.

3 ответа

Я пробовал много обходных путей, чтобы исправить это, как расширение класса, в котором есть функция getSelectedPos, которая возвращает позицию на основе начала с функцией, а не equals или equalignorecase. Но из-за закрытости метода класса NumberPicker это невозможно сделать. Я также попробовал другую работу вокруг, которая не работала.

Наконец-то я получил простое решение этой проблемы. Я создал свою собственную функцию для изменения данных, которые должны быть установлены на NumberPicker, прежде чем на NumberPicker.

modifyDataForNumberPicker(values);
np.setDisplayedValues(values);

private void modifyDataForNumberPicker(String[] dataList){
        int i=0;
        for(String data : dataList){
            int pos = i++;
            dataList[pos] = data+" ";
        }
    } 

Эта функция предотвращает подстроку любой строки из любой строки из данного массива, устанавливаемой в NumberPicker.

Я столкнулся с той же проблемой, и я решил ее, определив фиксированную ширину для NumberPicker.

      <NumberPicker
    android:id="@+id/np"
    android:layout_width="50dp" // <=== replace "wrap_content" with fixed width
    android:layout_height="0dp"
    android:layout_below="@id/tv"
    android:layout_weight="1"/>

Кажется, я нашел причину, по которой это произошло. Заглянув в исходный код NumberPicker, в функции getSelectedPos (строка 1819 на момент написания) мы видим следующее:

      private int getSelectedPos(String value) {
    if (mDisplayedValues == null) {
        try {
            return Integer.parseInt(value);
        } catch (NumberFormatException e) {
            // Ignore as if it's not a number we don't care
        }
    } else {
        for (int i = 0; i < mDisplayedValues.length; i++) {
            // Don't force the user to type in jan when ja will do
            value = value.toLowerCase();
            if (mDisplayedValues[i].toLowerCase().startsWith(value)) {
                return mMinValue + i;
            }
        }
        /*
         * The user might have typed in a number into the month field i.e.
         * 10 instead of OCT so support that too.
         */
        try {
            return Integer.parseInt(value);
        } catch (NumberFormatException e) {
            // Ignore as if it's not a number we don't care
        }
    }
    return mMinValue;
}

Этот код используется для приема вводимых пользователем данных в NumberPicker и преобразования их в фактическое значение из предоставленных отображаемых строк.

Я считаю, что здесь виноват цикл for в середине этой функции. Как если бы значение является подстрокой предыдущего значения в списке отображения, это приведет к тому, что эти два значения будут бороться за то, какое из них будет отображаться.

Есть еще одна функция, которая устанавливает отображение во время/после прокрутки, поэтому прокрутка исправляет визуальные эффекты.

Вот почему решение Ананда Кумара Джа работает: оно приводит к тому, что последующие значения больше не являются подстроками предыдущих.

Другие вопросы по тегам