【问题标题】:Android ListView with Switch onCheckedListener weird带有 Switch onCheckedListener 的 Android ListView 很奇怪
【发布时间】:2016-08-16 05:22:19
【问题描述】:

我对 android 开发相当陌生,并开始了一个小应用程序项目。现在我有一个问题,我似乎无法单独解决,并且在搜索中找不到解决方案。所以我希望你能给我一个建议:)

我有一个 ListView,其模板如下:

<Switch
    android:id="@+id/trackingSwitch"
    android:layout_columnSpan="1"
    android:layout_alignParentLeft="true"
    android:layout_row="0"
    android:layout_column="0" />

<TextView
    android:id="@+id/tvName"
    android:layout_columnSpan="1"
    android:text="Name"
    android:textColor="#545454"
    android:textSize="20dp"
    android:layout_marginLeft="10dp"
    android:layout_gravity="fill_horizontal"
    android:layout_row="0"
    android:layout_column="1" />

<TextView
    android:id="@+id/tvTime"
    android:layout_columnSpan="1"
    android:text="Time"
    android:textSize="15dp"
    android:textStyle="italic"
    android:layout_marginLeft="10dp"
    android:layout_gravity="fill_horizontal"
    android:layout_row="1"
    android:layout_column="1" />
 </GridLayout>

它工作得很好,给了我一个切换按钮和两个文本字段。现在我想用我的对象数据填充它,因此我扩展了一个 ArrayAdapter 并将它放在 getView() 中:

  @Override
  public View getView(int position, View view, ViewGroup parent) {
    // Get the data item for this position
    final AniTracking aniTracking = getItem(position);
    // Check if an existing view is being reused, otherwise inflate the view
    if (view == null) {
        view =      LayoutInflater.from(getContext()).inflate(R.layout.tracking_list, parent, false);
    }
    // Lookup view for data population
    Switch swActive = (Switch) view.findViewById(R.id.trackingSwitch);
    TextView tvName = (TextView) view.findViewById(R.id.tvName);
    TextView tvTime = (TextView) view.findViewById(R.id.tvTime);

    // Populate the data into the template view using the data object
    swActive.setChecked(aniTracking.isActive());
    tvName.setText(aniTracking.getName());
    tvTime.setText(aniTracking.getCurrentTrackingTime());


    // attach listener to switch
    swActive.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton compoundButton, boolean newStatus) {
            // switch set to active? start new AniTrackingPart
            if (newStatus == true) {
                AniTrackingPart aniTrackingPart = new AniTrackingPart();
                aniTrackingPart.setStartTime(new DateTime());
                AniTrackingManager.getInstance(getContext()).addAniTrackingPart(aniTracking, aniTrackingPart);
            }
            // set to inactive -> close current AniTrackingPart
            else {
                AniTrackingManager.getInstance(getContext()).closeActiveTrackingPart(aniTracking);
            }
        }
    });

    // Return the completed view to render on screen
    return view;
}

我的问题是 onCheckedChange 监听器。当我附加它时,开关的行为很奇怪,使每个项目的状态都为真。我注意到 getView() 方法被多次调用,我需要自己关心吗? 当我为位置 2 填充数据时,我也感觉可能会触发位置 1 的侦听器 (swActive.setChecked(aniTracking.isActive())),这可能吗?

感谢每一个帮助,这让我的进步停止了几天。

祝你有美好的一天, 阿尼

编辑以澄清不是重复的问题:如果 getView() 不会被多次调用,问题也会存在。由于 ListView 中的每个项目都调用了它,因此对 position > 1 的调用已经触发了我的侦听器并给了我错误的结果。

【问题讨论】:

标签: android listview switch-statement


【解决方案1】:

您的第一个问题是找出为什么您的notifyDataSetChanged 被多次调用。这将为所有可见视图触发 getView。

你的第二个问题,setChecked 会触发你的setOnCheckedChangeListener

您可以改用setOnClickListener 来避免这种情况:

    switch.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (switch.isChecked()) {

            } else {

            }
        }
    });

以确保仅在被触摸时调用它,而不是通过任何 ui 引起的更改。

(您还需要将开关更改为final Switch

【讨论】:

  • 谢谢,使用 OnClickListener 而不是 OnCheckedChangeListener 让一切正常工作:)
  • 请记住,滑动开关(而不是单击)不会触发此侦听器。
猜你喜欢
  • 1970-01-01
  • 2012-01-10
  • 1970-01-01
  • 1970-01-01
  • 2014-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多