2016-07-14 10 views
1

リストビューを使用していますが、アイテムをバインドするリストビューを使用しています。リストビューのビューを更新したいのですが、スクロールすると、スクロールする時間がランダムに変わる他のビューに適用されます。スクロールで無作為にリストビューが更新されます

これは私のコードです。

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:orientation="vertical"> 
<ListView 
    android:id="@+id/twvTest" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"></ListView> 
</LinearLayout> 

MainActivity.java

public class MainActivity extends Activity { 
ListView twvTest; 
ArrayList<DataModel> dataModels; 
NameListAdapter adapter; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    twvTest = (ListView) findViewById(R.id.twvTest); 

    dataModels = new ArrayList<>(); 
    adapter = new NameListAdapter(MainActivity.this, dataModels); 
    twvTest.setAdapter(adapter); 
    twvTest.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
     @Override 
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
      for (int i = 0; i < twvTest.getCount(); i++) { 
       TextView txtName = (TextView) view.findViewById(R.id.txtName); 
       if (i == position) { 
        txtName.setTextColor(Color.GREEN); 
        txtName.setBackgroundColor(Color.YELLOW); 
       } else { 
        txtName.setTextColor(Color.YELLOW); 
        txtName.setBackgroundColor(Color.GREEN); 
       } 
      } 
     } 
    }); 
    fillList(); 
} 

private void fillList() { 
    for (int i = 0; i < 30; i++) { 
     DataModel dataModel = new DataModel(); 
     dataModel.setName("Name : " + i); 
     dataModels.add(dataModel); 
    } 
    adapter.notifyDataSetChanged(); 
    } 
} 

NameListAdapter.java

public class NameListAdapter extends BaseAdapter { 
Context context; 
ArrayList<DataModel> dataModels; 
LayoutInflater inflater; 

public NameListAdapter(Context context, ArrayList<DataModel> dataModels) { 
    this.context = context; 
    this.dataModels = dataModels; 
    inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
} 

@Override 
public int getCount() { 
    return dataModels.size(); 
} 

@Override 
public Object getItem(int position) { 
    return dataModels.get(position); 
} 

@Override 
public long getItemId(int position) { 
    return dataModels.indexOf(getItem(position)); 
} 

private class Holder { 
    TextView txtName; 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    Holder holder; 
    if (convertView == null) { 
     holder = new Holder(); 
     convertView = inflater.inflate(R.layout.test_adapter_raw, parent, false); 
     holder.txtName = (TextView) convertView.findViewById(R.id.txtName); 
     convertView.setTag(holder); 
    } else { 
     holder = (Holder) convertView.getTag(); 
    } 
    holder.txtName.setText(dataModels.get(position).getName()); 
    return convertView; 
    } 
} 

test_adapter_raw.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="100dp" 
android:background="#ffffff" 
android:orientation="vertical"> 

<TextView 
    android:id="@+id/txtName" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:layout_margin="5dp" 
    android:background="#949494" 
    android:gravity="center" 
    android:text="Text" 
    android:textAppearance="?android:attr/textAppearanceMedium" 
    android:textColor="#fff" 
    android:textStyle="bold" /> 
</LinearLayout> 

DataModel.java

public class DataModel { 
String name; 

public String getName() { 
    return name; 
} 

public void setName(String name) { 
    this.name = name; 
} 
} 
+0

こんにちはTechskyは、次のようにあなたのlistItemsルートレイアウトのIDを使用してください。ビューは再利用されるので、onClickListener内で色を直接変更することはできません。アダプタを更新してから、アダプタがビューの色を制御します。 – W0rmH0le

答えて

0

これは、ListViewが再生回数をリサイクルするために発生します。したがって、他のポジションでも同じビューが使用されています。混乱を避けるには、アダプタ内でクリックリスナーを設定し、ホルダー内の色を処理します。

public class NameListAdapter extends BaseAdapter { 
Context context; 
ArrayList<DataModel> dataModels; 
LayoutInflater inflater; 

public NameListAdapter(Context context, ArrayList<DataModel> dataModels) { 
this.context = context; 
this.dataModels = dataModels; 
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
} 

@Override 
public int getCount() { 
    return dataModels.size(); 
} 

@Override 
public Object getItem(int position) { 
    return dataModels.get(position); 
} 

@Override 
public long getItemId(int position) { 
    return dataModels.indexOf(getItem(position)); 
} 

private class Holder { 
    TextView txtName; 
    LinearLayout root_layout; 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    Holder holder; 
    if (convertView == null) { 
     holder = new Holder(); 
     convertView = inflater.inflate(R.layout.test_adapter_raw, parent, false); 
     holder.txtName = (TextView) convertView.findViewById(R.id.txtName); 
     holder.root_layout=(LinearLayout)convertView.findViewById(R.id.root_layout) 
     convertView.setTag(holder); 
    } else { 
     holder = (Holder) convertView.getTag(); 
    } 
    holder.txtName.setText(dataModels.get(position).getName()); 

    holder.root_layout.setOnClickListener(new View.OnClickListener(){ 

       holder.txtName.setTextColor(Color.GREEN); 
       holder.txtName.setBackgroundColor(Color.YELLOW); 

       //implement your own logic to remove color on second click 
    }); 


    return convertView; 
    } 
} 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:id="@+id/root_layout" 
android:layout_width="match_parent" 
android:layout_height="100dp" 
android:background="#ffffff" 
android:orientation="vertical"> 

<TextView 
android:id="@+id/txtName" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:layout_margin="5dp" 
android:background="#949494" 
android:gravity="center" 
android:text="Text" 
android:textAppearance="?android:attr/textAppearanceMedium" 
android:textColor="#fff" 
android:textStyle="bold" /> 
</LinearLayout> 
+0

これを使用するとOnItemClickListenerを削除します - >ビューを保持するメンバーとクリックを関連させると混乱を防ぎます – Kushan

+0

あなたの回答と貴重な努力に感謝します。しかし、その値に基づいてリストビューをクリックすると他のリストビューをバインドする必要があります。それはMainActivityにあります。なぜ私はアクティビティの更新ビューを使用して、この値に基づいて別のリストビューの値をフィルタリングする必要があります。 –

+0

こんにちは..申し訳ありませんでしたあなたとそれを助けることができませんでした。とにかく、あなたは今、混乱が起こっていた理由を知っています。 ViewHolderを使って色などを設定する方法... RecyclerViewを試してみると、ViewHolderを強制的に使用するようになり、リストビューよりもはるかに効率的です。 – Kushan

0

ビューが再使用されているので、あなたがonClick()の間に直接のビューを変更することはできません....

をだから、あなたは、ビューの色を変更し、そのビューになりますおそらく別の位置で再使用され、別の位置にカラー表示が表示されます。

アダプタの表示色を制御する必要があります。この方法では、アクティビティはアダプタを更新し、notifyDataSetChanged()を呼び出して、ListViewでコンテンツを更新します。

あなたのアクティビティコード

twvTest.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
    @Override 
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
     // Inform the adapter that following item should be displayed in Yellow 
     adapter.displayViewInYellow(position); 
     adapter.notifyDataSetChanged();   
    } 
}); 

あなたのアダプタのコード

public class NameListAdapter extends BaseAdapter { 

    boolean [] arrayOfViewsThatMustShowYellow; 

    public NameListAdapter(Context context, ArrayList<DataModel> dataModels) { 
     ... 
     arrayOfViewsThatMustShowYellow = new boolean[getCount()]; 
    } 

    public void displayViewInYellow(int position) { 
     // boolean array to track view that must be displayed in Yellow 
     arrayOfViewsThatMustShowYellow[position] = true; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 

     ..... 

     // Following code could be simplified to convertView.setEnabled(arrayOfViewsThatMustShowYellow[position]) 
     if(arrayOfViewsThatMustShowYellow[position] == true) { 
      holder.txtName.setTextColor(Color.GREEN); 
      holder.txtName.setBackgroundColor(Color.YELLOW); 
     } else { 
      holder.txtName.setTextColor(Color.YELLOW); 
      holder.txtName.setBackgroundColor(Color.GREEN); 
     } 
    } 
} 

これは一例です...それはちょうどについての考えを共有することですそれを行う方法... ビューを更新する必要がある場合は、アダプター内でこの変更を追跡する必要があります(ClickListenersまたはActivityでは決して外側にはありません)。

+0

こんにちは、ありがとうございます。私はアダプタ内の問題は何かを知りたがっていました。あなたは、私たちはアダプタ内のlistviewのすべてのリスナーを行う必要があると言ったが、私のアプリでは、グリッドビューとアダプタ内で使用されているすべてのリスナを使用して同じ問題が発生した別の活動があります。あなたはリンク[Gridviewアダプタの問題](http://stackoverflow.com/questions/38247794/listview-update-another-raw-on-update-of-selected-raw) –

0

名前に空の値がある場合、ビューの所有者は、空の名前のit.set ""のramdom値を設定します。

+0

を見ることができますしかし、私は空の名前を持っていません –

+0

問題がスクロールします –

関連する問題