В Android, учитывая ListView элементов с TextView и RadioGroup, как динамически добавлять элементы? - PullRequest
0 голосов
/ 14 июля 2020

Мне нужно управлять ListView, чтобы каждый элемент имел textView и RadioGroup. Ниже приведен файл xml для одного элемента: controls_layout_row. 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:orientation="vertical"
    android:padding="20dp"
    android:background="@drawable/fragment_template"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/control_name"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textColor="#ffffff"
        android:textSize="20sp"
        android:textStyle="bold"
        android:layout_marginBottom="5dp"/>

    <RadioGroup
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/control_name"
        android:id="@+id/control_options_list"
        android:layout_marginBottom="20dp"
        tools:layout_height="150dip">
        <!-- items added within code -->
    </RadioGroup>

</RelativeLayout>

Элементы являются частью ListView - ниже показан файл xml для ListView :

control_dialog. 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:orientation="vertical"
    android:padding="20dp"
    android:background="@drawable/fragment_template"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/controls_list_title"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textColor="#ffffff"
        android:text="Controls"
        android:textSize="20dp"
        android:textStyle="bold"
        android:layout_marginBottom="5dp"/>

    <ListView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/controls_list_title"
        android:id="@+id/controls_list"
        tools:layout_height="150dip">
        <!-- items added within code -->
    </ListView>

    //Close button
    <Button android:id="@+id/controls_close_button"
        android:layout_below="@id/controls_list"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="14dp"
        android:text="Close"
        android:layout_alignParentEnd="true"
        android:textAllCaps="false"
        android:textStyle="bold"/>
</RelativeLayout>

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

Первый метод: просто каждый раз создавайте какой-нибудь элемент и добавляйте его представление в список:

    // retrieve item view
    final View emittersRowView = inflater.inflate(R.layout.controls_layout_row, null);
    // set TextView
    final TextView emitterTitle = emittersRowView.findViewById(R.id.control_name);
    emitterTitle.setText("Projector");
    //set RadioGroup
    final String emitterDescriptions[] = getOptionDescriptions(Option.EMITTER_ENABLED);
    final RadioGroup emittersRadioGroup = emittersRowView.findViewById(R.id.control_options_list);
    // adding buttons to the group
    for(int i = 0; i < emitterDescriptions.length; ++i) {
        RadioButton button = new RadioButton(activity);
        button.setId(i);
        button.setText(emitterDescriptions[i]);
        button.setTextColor(getResources().getColor(R.color.white));
        button.setChecked(i == indexOfCurrentEmitter);
        emittersRadioGroup.addView(button);
    }

    emittersRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener(){
        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId) {
            List<Sensor> sensors = mDevice.querySensors();
            for (Sensor s : sensors) {
                if (s.supports(Option.EMITTER_ENABLED)) {
                    s.setValue(Option.EMITTER_ENABLED, checkedId);
                }
            }
        }
    });

    //add control to list
    ListView controlsList = fragmentView.findViewById(R.id.controls_list);
    controlsList.addView(emittersRowView);

Этот способ не сработал. Я читал на других форумах, что это не может работать без использования адаптера. Мне это кажется странным, потому что использование метода addView объекта RadioGroup для добавления объектов RadioButton отлично работает.

Второй метод : Использование настраиваемого адаптера: я определил adpater и мой план состоял в том, чтобы сначала построить:

  • массив String для объектов TextView
  • список объектов RadioGroup для объектов RadioGroup, а затем использовать их для создания адаптера. Но когда я добрался до кода, я застрял, не зная, как установить RadioGroup в адаптере:

Код адаптера:

   class CustomAdapter extends BaseAdapter {

    @Override
    public int getCount() {
        return numOfControls;
    }

    @Override
    public Object getItem(int position) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final Activity activity = getActivity();
        convertView = activity.getLayoutInflater().inflate(R.layout.controls_layout_row, null);

        TextView control_name = convertView.findViewById(R.id.control_name);
        RadioGroup control_options = convertView.findViewById(R.id.control_options_list);

        control_name.setText(mControlNames[i]);
        control_options.set....???
        return convertView;
    }
}

Пожалуйста, помогите мне заставить его работать.

1 Ответ

1 голос
/ 15 июля 2020

Начните новый проект и попробуйте полный пример кода ниже:

MainActivity. java:

public class MainActivity extends AppCompatActivity {

class Control {
    String name;
    String[] options;
    int checkedPosition = -1;

    public Control(String name, String[] options) {
        this.name = name;
        this.options = options;
    }
    public String getName() {
        return name;
    }
    public String[] getOptions() {
        return options;
    }
    public int getCheckedPosition() {
        return checkedPosition;
    }
    public void setCheckedPosition(int checkedPosition) {
        this.checkedPosition = checkedPosition;
    }
}

Control[] controls = new Control[10];

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

    ListView controlsList = findViewById(R.id.controls_list);
    createSampleData();
    CustomAdapter adapter = new CustomAdapter(this, 0, controls);
    controlsList.setAdapter(adapter);

    Button button = findViewById(R.id.controls_close_button);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            String msg = "";
            for (int i = 0; i < controls.length; i++) {
                msg += controls[i].getName() + " , " + controls[i].getCheckedPosition() + "\n";
            }
            Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
        }
    });
}

private void createSampleData() {
    Random random = new Random();
    for (int i = 0; i < controls.length; i++) {
        int j = random.nextInt(4) + 2;
        String[] options = new String[j];
        for (int k = 0; k < j; k++) {
            options[k] = (i + 1) + "-" + k;
        }
        controls[i] = new Control("Control " + (i + 1), options);
    }
}
}

CustomAdapter. java:

public class CustomAdapter extends ArrayAdapter {

Context context;
LayoutInflater inflater;

public CustomAdapter(@NonNull Context context, int resource, @NonNull MainActivity.Control[] objects) {
    super(context, resource, objects);
    this.context = context;
    inflater = LayoutInflater.from(context);
}

@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
    convertView = inflater.inflate(R.layout.controls_layout_row, null);

    TextView control_name = convertView.findViewById(R.id.control_name);
    RadioGroup control_options = convertView.findViewById(R.id.control_options_list);

    MainActivity.Control control = (MainActivity.Control)getItem(position);
    control_name.setText(control.getName());

    String[] options = control.getOptions();
    for(int i = 0; i < options.length; i++) {
        RadioButton button = new RadioButton(context);
        button.setId(i);
        button.setText(options[i]);
        button.setTextColor(Color.WHITE);
        button.setChecked(i == control.getCheckedPosition());
        control_options.addView(button);
    }
    control_options.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(RadioGroup radioGroup, int i) {
            int pos = (int)radioGroup.getTag();
            MainActivity.Control changedControl = (MainActivity.Control)getItem(pos);
            changedControl.setCheckedPosition(i);
        }
    });
    control_options.setTag(position);

    return convertView;
}
}

используйте размещенные вами макеты.

...