Android的ListView控件与切换按钮 [英] Android ListView with toggle button
问题描述
我有,当我的ListView具有可以在屏幕上会出现更多的itens一个问题;换言之,当它到达滚动。问题是,当我在切换按钮一按,这是改变的ImageView的知名度。然而,当我点击它,它正在改变比相应的点击更多的知名度。
我使用的适配器以显示列表itens。
我添加下面的code:
公共类CriteriosAdapter扩展ArrayAdapter<&搜索标准GT; {私人上下文的背景下;公共CriteriosAdapter(上下文的背景下,列表与LT;搜索标准>对象){
超(背景下,0,对象);
this.context =背景;
}@覆盖
公共查看getView(INT位置,查看convertView,父母的ViewGroup){
最终的搜索标准搜索标准=的getItem(位置);
最后CriterioViewHolder viewHolder; 如果(convertView == NULL){
convertView = LayoutInflater.from(的getContext())膨胀(R.layout.fragment_row,父母,假的)。 viewHolder =新CriterioViewHolder();
viewHolder.txtCriterio =(TextView中)convertView.findViewById(R.id.txtCriterio);
viewHolder.tgIrregular =(切换按钮)convertView.findViewById(R.id.tgIrregular);
viewHolder.btnCam =(ImageView的)convertView.findViewById(R.id.btnCam); convertView.setTag(viewHolder);
}
其他{
viewHolder =(CriterioViewHolder)convertView.getTag();
} viewHolder.txtCriterio.setText(criterio.nome);
viewHolder.txtCriterio.setTextColor(context.getColor(R.color.white));
viewHolder.tgIrregular.setChecked(假); viewHolder.tgIrregular.setOnClickListener(新View.OnClickListener(){
@覆盖
公共无效的onClick(视图v){
如果(viewHolder.tgIrregular.isChecked()){
viewHolder.btnCam.setVisibility(View.VISIBLE);
}其他{
viewHolder.btnCam.setVisibility(View.INVISIBLE);
}
}
}); viewHolder.btnCam.setOnClickListener(新View.OnClickListener(){
公共无效的onClick(查看为arg0){
FragmentActivity活性=(FragmentActivity)(上下文);
android.support.v4.app.FragmentManager FM = activity.getSupportFragmentManager();
FotosFragment alertDialog =新FotosFragment();
alertDialog.show(FM,fragment_alert);
}
}); 返回convertView;
}类CriterioViewHolder { TextView的txtCriterio;
切换按钮tgIrregular; ImageView的btnCam;}}
有人能帮助我吗?
感谢您。
修改
我说的一切,你描述。但是,我用适配器5片段,如果我去了一个,回来或滚动列表,它仍然失去了价值。
我用criterio.getHash,因为它是所有独特。和位置,可以在其他片段重复,并使其不可思议。
公共类CriteriosAdapter扩展ArrayAdapter<&搜索标准GT; {私人上下文的背景下;
公共静态地图<字符串搜索标准> irregularidades =新的HashMap<字符串搜索标准>();
HashMap的<字符串,布尔值> toggleButtonStateTracker =新的HashMap<>();公共CriteriosAdapter(上下文的背景下,列表与LT;搜索标准>对象){
超(背景下,0,对象);
this.context =背景;
}@覆盖
公共查看getView(INT位置,查看convertView,父母的ViewGroup){
最终的搜索标准搜索标准=的getItem(位置);
最后CriterioViewHolder viewHolder; 如果(!toggleButtonStateTracker.containsKey(criterio.getHash())){
toggleButtonStateTracker.put(criterio.getHash(),FALSE);
} Log.e(切换曲目:toggleButtonStateTracker.toString()); 如果(convertView == NULL){
convertView = LayoutInflater.from(的getContext())膨胀(R.layout.fragment_row,父母,假的)。 viewHolder =新CriterioViewHolder();
viewHolder.txtCriterio =(TextView中)convertView.findViewById(R.id.txtCriterio);
viewHolder.tgIrregular =(切换按钮)convertView.findViewById(R.id.tgIrregular);
viewHolder.btnCam =(ImageView的)convertView.findViewById(R.id.btnCam); convertView.setTag(viewHolder);
}
其他{
viewHolder =(CriterioViewHolder)convertView.getTag();
} viewHolder.txtCriterio.setText(criterio.nome);
如果(Build.VERSION.SDK_INT> = Build.VERSION_ codeS.M){
viewHolder.txtCriterio.setTextColor(context.getColor(R.color.white));
}其他{
viewHolder.txtCriterio.setTextColor(context.getResources()的getColor(R.color.white));
} viewHolder.tgIrregular.setId(criterio.id); 最终布尔器isChecked = toggleButtonStateTracker.get(criterio.getHash());
viewHolder.tgIrregular.setChecked(器isChecked); viewHolder.btnCam.setTag(criterio.hash); 如果(器isChecked){
viewHolder.btnCam.setVisibility(View.VISIBLE);
}其他{
viewHolder.btnCam.setVisibility(View.INVISIBLE);
} viewHolder.tgIrregular.setOnCheckedChangeListener(新CompoundButton.OnCheckedChangeListener(){
@覆盖
公共无效onCheckedChanged(CompoundButton buttonView,布尔器isChecked){
toggleButtonStateTracker.put(criterio.getHash(),器isChecked);
如果(器isChecked){
viewHolder.btnCam.setVisibility(View.VISIBLE);
irregularidades.put(criterio.getHash(),搜索标准);
}其他{
viewHolder.btnCam.setVisibility(View.INVISIBLE);
irregularidades.remove(criterio.getHash());
}
}
}); viewHolder.btnCam.setOnClickListener(新View.OnClickListener(){
公共无效的onClick(查看为arg0){
FragmentActivity活性=(FragmentActivity)(上下文);
android.support.v4.app.FragmentManager FM = activity.getSupportFragmentManager();
FotosFragment alertDialog =新FotosFragment(); 捆绑ARGS =新包();
args.putString(criterioTag,criterio.getHash());
alertDialog.setArguments(参数); alertDialog.setCancelable(假);
alertDialog.show(FM,fragment_alert);
}
}); 返回convertView;
}类CriterioViewHolder { TextView的txtCriterio;
切换按钮tgIrregular;
ImageView的btnCam;}}
您的问题是,由于意见在的ListView
回收(和 RecyclerView
)下发生在你身上:
- 您设置的可视性
的ImageView
一排隐形与切换按钮
- 您的行获取滚动的视线之外,因此得到回收。
- 循环使用的观点仍具有
的ImageView
与visilibility设置为View.INVISIBLE
- 您指定新值的行,但不改变能见度
要解决这个问题,你应该有一个列表
,的HashMap
或任何类似,并跟踪其切换按钮
检查和的ImageView
可见。 (你可以做到这一点的位置)
然后在你的公共查看getView(INT位置,查看convertView,一个ViewGroup父)
方法,你检查这posision的(行)形象应该是可见或不可见,并设置因此与 viewHolder.btnCam.setVisibility()
和切换按钮
为好。
修改
这个成员变量添加到您的适配器结果的HashMap<整数,布尔> toggleButtonStateTracker =新的HashMap<取代;
在您getView添加此
如果(!toggleButtonStateTracker.containsKey(位置)){
//现在HashMap中肯定包含密钥
toggleButtonStateTracker.put(位置,FALSE);
}布尔=器isChecked toggleButtonStateTracker.get(位置);
viewHolder.tgIrregular.setChecked(器isChecked);
如果(器isChecked){
//如果切换按钮被选中时,btnCam应该是不可见
viewHolder.btnCam.setVisibility(View.INVISIBLE);
}其他{
viewHolder.btnCam.setVisibility(View.VISIBLE);
}
最后添加此tgIrregular
viewHolder.tgIrregular.setOnCheckedChangedListener(新CompoundButton.OnCheckedChangeListener(){
@覆盖
公共无效onCheckedChanged(CompoundButton buttonView,布尔器isChecked){
toggleButtonStateTracker.put(getAdapterPosition,器isChecked);
}
});
I'm having a problem when my ListView has more itens that can appear on the screen; in other words, when it gets scroll. The problem is, when I click in one of the toggle buttons, it's change the visibility of the ImageView. However, when I click on it, it is changing the visibility of more than the respective clicked.
I'm using an adapter to display the list itens.
I added the code below:
public class CriteriosAdapter extends ArrayAdapter<Criterio> {
private Context context;
public CriteriosAdapter(Context context, List<Criterio> objects) {
super(context, 0, objects);
this.context = context;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final Criterio criterio = getItem(position);
final CriterioViewHolder viewHolder;
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.fragment_row, parent, false);
viewHolder = new CriterioViewHolder();
viewHolder.txtCriterio = (TextView)convertView.findViewById(R.id.txtCriterio);
viewHolder.tgIrregular = (ToggleButton)convertView.findViewById(R.id.tgIrregular);
viewHolder.btnCam = (ImageView) convertView.findViewById(R.id.btnCam);
convertView.setTag(viewHolder);
}
else {
viewHolder = (CriterioViewHolder)convertView.getTag();
}
viewHolder.txtCriterio.setText(criterio.nome);
viewHolder.txtCriterio.setTextColor(context.getColor(R.color.white));
viewHolder.tgIrregular.setChecked(false);
viewHolder.tgIrregular.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (viewHolder.tgIrregular.isChecked()) {
viewHolder.btnCam.setVisibility(View.VISIBLE);
} else {
viewHolder.btnCam.setVisibility(View.INVISIBLE);
}
}
});
viewHolder.btnCam.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
FragmentActivity activity = (FragmentActivity)(context);
android.support.v4.app.FragmentManager fm = activity.getSupportFragmentManager();
FotosFragment alertDialog = new FotosFragment();
alertDialog.show(fm, "fragment_alert");
}
});
return convertView;
}
class CriterioViewHolder {
TextView txtCriterio;
ToggleButton tgIrregular;
ImageView btnCam;
}
}
Could someone help me with it?
Thank you.
EDIT
I added everything as you describe. However, I use that adapter in 5 fragments, if I go to another, and come back or scroll the list, it still lost the value.
I used criterio.getHash, because it is unique for all. And position, can repeat in other fragment, and make it weird.
public class CriteriosAdapter extends ArrayAdapter<Criterio> {
private Context context;
public static Map<String, Criterio> irregularidades = new HashMap<String, Criterio>();
HashMap<String, Boolean> toggleButtonStateTracker = new HashMap<>();
public CriteriosAdapter(Context context, List<Criterio> objects) {
super(context, 0, objects);
this.context = context;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final Criterio criterio = getItem(position);
final CriterioViewHolder viewHolder;
if (!toggleButtonStateTracker.containsKey(criterio.getHash())){
toggleButtonStateTracker.put(criterio.getHash(),false);
}
Log.e("Toggle Track:", toggleButtonStateTracker.toString());
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.fragment_row, parent, false);
viewHolder = new CriterioViewHolder();
viewHolder.txtCriterio = (TextView)convertView.findViewById(R.id.txtCriterio);
viewHolder.tgIrregular = (ToggleButton)convertView.findViewById(R.id.tgIrregular);
viewHolder.btnCam = (ImageView) convertView.findViewById(R.id.btnCam);
convertView.setTag(viewHolder);
}
else {
viewHolder = (CriterioViewHolder)convertView.getTag();
}
viewHolder.txtCriterio.setText(criterio.nome);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
viewHolder.txtCriterio.setTextColor(context.getColor(R.color.white));
} else {
viewHolder.txtCriterio.setTextColor(context.getResources().getColor(R.color.white));
}
viewHolder.tgIrregular.setId(criterio.id);
final boolean isChecked = toggleButtonStateTracker.get(criterio.getHash());
viewHolder.tgIrregular.setChecked(isChecked);
viewHolder.btnCam.setTag(criterio.hash);
if (isChecked) {
viewHolder.btnCam.setVisibility(View.VISIBLE);
} else {
viewHolder.btnCam.setVisibility(View.INVISIBLE);
}
viewHolder.tgIrregular.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
toggleButtonStateTracker.put(criterio.getHash(), isChecked);
if (isChecked) {
viewHolder.btnCam.setVisibility(View.VISIBLE);
irregularidades.put(criterio.getHash(), criterio);
} else {
viewHolder.btnCam.setVisibility(View.INVISIBLE);
irregularidades.remove(criterio.getHash());
}
}
});
viewHolder.btnCam.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
FragmentActivity activity = (FragmentActivity) (context);
android.support.v4.app.FragmentManager fm = activity.getSupportFragmentManager();
FotosFragment alertDialog = new FotosFragment();
Bundle args = new Bundle();
args.putString("criterioTag", criterio.getHash());
alertDialog.setArguments(args);
alertDialog.setCancelable(false);
alertDialog.show(fm, "fragment_alert");
}
});
return convertView;
}
class CriterioViewHolder {
TextView txtCriterio;
ToggleButton tgIrregular;
ImageView btnCam;
}
}
Your issue is due to the recycling of Views in ListView
(and RecyclerView
) The following happens to you:
- You set visibility of an
ImageView
in one row to invisible with yourToggleButton
- Your row gets scrolled out of sight and therefore gets recycled.
- The recycled view still has an
ImageView
with visilibility set toView.INVISIBLE
- You assign your new values to the row but don't change the visibility
To solve this you should have a List
, HashMap
or anything similar and track which ToggleButton
is checked and which ImageView
is visible. (You can do that with the position)
Then in your public View getView(int position, View convertView, ViewGroup parent)
method you check if this posision's (rows) image should be visible or not and set it accordingly with viewHolder.btnCam.setVisibility()
and the ToggleButton
as well.
EDIT
Add this member variable to your adapter
HashMap<Integer,Boolean> toggleButtonStateTracker = new HashMap<>;
In your getView add this
if (! toggleButtonStateTracker.containsKey(position)){
// Now the HashMap definitely contains the key
toggleButtonStateTracker.put(position,false);
}
boolean isChecked = toggleButtonStateTracker.get(position);
viewHolder.tgIrregular.setChecked(isChecked);
if (isChecked){
// if your toggle Button is checked, the btnCam should be invisible
viewHolder.btnCam.setVisibility(View.INVISIBLE);
} else {
viewHolder.btnCam.setVisibility(View.VISIBLE);
}
And finally add this tgIrregular
viewHolder.tgIrregular.setOnCheckedChangedListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
toggleButtonStateTracker.put(getAdapterPosition, isChecked);
}
});
这篇关于Android的ListView控件与切换按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!