繁体   English   中英

在 Android 中,给定带有 TextView 和 RadioGroup 的项目的 ListView,如何动态添加项目?

[英]In Android, given a ListView of items with TextView and RadioGroup, how to add items dynamically?

我需要管理一个 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 的一部分 - 以下是 ListView 的 xml 文件:

控制对话框.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 接口从连接的硬件获取信息,然后在活动中使用一些 getter 以了解哪些项目必须出现在对话框中。 我尝试了两种方法,但都陷入了困境。

第一种方法:每次我需要时只需创建一些项目并将其视图添加到列表中:

    // 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);

这种方法没有奏效。 我在其他论坛上读到,如果不使用 adpater,这将无法工作。 这对我来说似乎很奇怪,因为使用 RadioGroup object 上的 addView 方法来添加 RadioButton 对象效果很好。

第二种方法:使用自定义适配器:我已经定义了一个适配器,我的计划是首先构建:

  • 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;
    }
}

请帮助我使它工作。

开始一个新项目并尝试下面的完整示例代码,

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;
}
}

使用您发布的布局。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM