2016-08-16 14 views
1

私はAndroid開発にかなり慣れていて、少しのアプリプロジェクトを開始しました。今私は一人で解決できないような問題があり、検索で解決策が見つからない。だから私はあなたが私のためのアドバイスを持っていただければ幸いです:)スイッチonCheckedListener weirdを使用したAndroidリストビュー

私はこのようなテンプレートを使用してリストビューを持っている:

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

それは右私のスイッチボタンと2つのテキストフィールドを与え、非常によく動作しますそれに。今私は)ので、私は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()メソッドが位置に対して複数回呼び出されていることに気付きました。私はそれを気にする必要がありますか? position2(swActive.setChecked(aniTracking.isActive()))のデータを設定すると、リスナーがposition1に対してトリガされる可能性があります。

私はすべての助けに感謝しています。これで数日間は私の進歩が止まります。 getViewメソッドは、()を複数回呼び出すことがないならば、問題も存在するでしょう:

は重複質問されていない明確にするために、素敵な一日 アニ

編集を持っています。 ListViewの各項目に対して呼び出されるので、position> 1の呼び出しはすでにリスナーをトリガーし、私に偽の結果を与えます。

+0

[リストビュー - getViewメソッドは、あまりにも多くの時間と呼ばれている]の可能な重複(http://stackoverflow.com/questions/9157523/listview-getview-いわゆる「too-much-times」) – Soham

答えて

1

あなたの最初の問題は、なぜあなたのnotifyDataSetChangedが何度も呼び出されている理由を見つけることです。これにより、すべての表示可能なビューに対してgetViewがトリガーされます。

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

      } else { 

      } 
     } 
    }); 

それは触れていますとき、それはだけでなく、任意のUI誘発性の変化によって、呼ばれていますことを確認する:

あなたの第二の問題、setCheckedはあなたのsetOnCheckedChangeListener

があなたの代わりにsetOnClickListenerを使用することによってこれを避けることができますトリガされます。

(あなたもfinal Switchにあなたのスイッチを変更する必要があります)

+0

おかげさまで、OnCheckedChangeListenerの代わりにOnClickListenerを使用すると、すべての作業が完了しました:) – Ani

関連する問題