滚动时,Android Listview重置更改

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了滚动时,Android Listview重置更改相关的知识,希望对你有一定的参考价值。

我正在使用带有自定义适配器的ListFragment。

我的适配器有一个textview和一个带箭头的隐藏imageview。当用户选择项目时,箭头显示并且背景颜色发生变化。但是,当用户滚动列表时,所有更改都将恢复为默认值。

我应该怎么做才能解决这些变化?

编辑:

我的适配器类..

public class PropriedadeAdapter extends BaseAdapter {
private Context context;
private List<Propriedades> prop;

public PropriedadeAdapter(Context context, List<Propriedades> prop) {
    this.context = context;
    this.prop = prop;
}

public int getCount() {
    return prop.size();
}

public Object getItem(int position) {
    return prop.get(position);
}

public long getItemId(int position) {
    return position;
}

public View getView(int position, View convertView, ViewGroup parent) {
    // Recupera o produto da posição atual
    Propriedades p = prop.get(position);

    // Layout XML
    int arquivoLayout = R.layout.lista_prop;
    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View v = inflater.inflate(arquivoLayout, null);

    // Atualiza o valor do Text para o nome do produto
    TextView textNome = (TextView) v.findViewById(R.id.nome);
    textNome.setText(p.getNome());

    return v;
}
}

我的片段课..

public class frag_lista extends ListFragment{

ImageView ultimoItem = null;

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
     ArrayList<Propriedades> props = new ArrayList<Propriedades>();
    for(int i = 0; i <50; i++)
    {
        Propriedades prop = new Propriedades();
        prop.setNome("FRUTA "+i);
        props.add(prop);
    }
    setListAdapter(new PropriedadeAdapter(this.getActivity(),props));
}


@Override
public void onListItemClick(ListView l, View v, int position, long id) {
    ImageView seta = (ImageView)v.findViewById(R.id.imgSeta);
    seta.setVisibility(0);
    LinearLayout linha = (LinearLayout)v.findViewById(R.id.linha);
    linha.setBackgroundColor(Color.GRAY);
    if(ultimoItem != null)
    {
        ultimoItem.setVisibility(4);
    }
    ultimoItem = seta;
}   

}

我该怎么做才能坚持onListItemClick方法的变化????

答案

根据您的评论,我认为您没有正确使用适配器。

Adapter提供ListView自动调用的方法。

您应该在内存中保留选定的索引,并在每次调用getView(...)方法时恢复View状态(从position参数jusging)。

查找有关ListView和Adapter的教程。

编辑:

请注意,我没有测试代码,但它可能是这样的:

// TeddyBearFr: Class name typically starts with a capital letter! Frag_lista, not frag_lista
public class frag_lista extends ListFragment{

    ImageView ultimoItem = null;

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
         ArrayList<Propriedades> props = new ArrayList<Propriedades>();
        for(int i = 0; i <50; i++)
        {
            Propriedades prop = new Propriedades();
            prop.setNome("FRUTA "+i);
            props.add(prop);
        }
        setListAdapter(new PropriedadeAdapter(this.getActivity(),props));
    }


    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {

        // TeddyBearFr: notify the adapter
        ( (PropriedadeAdapter) this.getListAdapter() ).onListItemClick(position);

        // TeddyBearFr: your last item must be managed in the getView(...) method of the Adapter
        //if(ultimoItem != null)
        //{
        //  ultimoItem.setVisibility(4);    // TeddyBearFr: don't use integer like this, use android constants! View.INVISIBLE
        //}
        //ultimoItem = seta;
    }   

}


public class PropriedadeAdapter extends BaseAdapter {
    private final static String TAG = "PropriedadeAdapter";
    private Context context;
    private List<Propriedades> prop;
    private Set<Integer> mSelectedItemsPosition;

    public PropriedadeAdapter(Context context, List<Propriedades> prop) {
        this.context = context;
        this.prop = prop;
        // TeddyBearFr: set to store selected indexes
        this.mSelectedItemsPosition = new HashSet<Integer>();
    }

    public int getCount() {
        return prop.size();
    }

    public Object getItem(int position) {
        return prop.get(position);
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        Log.d(TAG, "getView(position=" + position + ", convertView=" + convertView + ", parent=" + parent + ")" );

        // Recupera o produto da posição atual
        Propriedades p = prop.get(position);

        // TeddyBearFr: use existing view if exist ; otherwise create a new one
        View v;
        if( convertView == null ){
            // Layout XML
            int arquivoLayout = R.layout.lista_prop;
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = inflater.inflate(arquivoLayout, null);
        }
        else{
            v = convertView;
        }

        // Atualiza o valor do Text para o nome do produto
        TextView textNome = (TextView) v.findViewById(R.id.nome);
        textNome.setText(p.getNome());

        // TeddyBearFr: update view according its selection state
        ImageView seta = (ImageView)v.findViewById(R.id.imgSeta);
        boolean isViewSelected = this.mSelectedItemsPosition.contains(position);
        int visibility = ( isViewSelected ? VIEW.VISIBLE : VIEW.GONE );
        seta.setVisibility(visibility);

        LinearLayout linha = (LinearLayout)v.findViewById(R.id.linha);
        linha.setBackgroundColor( isViewSelected ? Color.GRAY : Color.RED );

        if( position == getCount()-1 ){
            // perform special processes on the last item of the list if needed
        }

        return v;
    }

    // TeddyBearFr: callback when click
    public void onListItemClick(int position){
        Log.d(TAG, "onListItemClick(position=" + position + ")");

        // update selected index data
        // Note that I haven't tested if it works. Because native integer "position" will be wrapped in Integer object, there's a chance that the Set compares the references on objects instead of their value
        if( this.mSelectedItemsPosition.contains(position) ){
            this.mSelectedItemsPosition.remove(position);
        }
        else{
            this.mSelectedItemsPosition.add(position);
        }

        // ask the list to be refreshed -> you'll see that getView() will be called only for each displayed view
        this.notifyDataSetChanged();
    }

}
另一答案

convertView有两个状态,它们是null而不是null。您的问题发生是因为eveytime yout getView()调用新的布局inflater实例正在初始化。仅当convertView为null时才初始化inflater。

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

    Propriedades p = prop.get(position); 
    int arquivoLayout = R.layout.lista_prop;

    View v;

    if (convertView==null){
        v = inflater.inflate(arquivoLayout, null);
    }
    else {
        v = convertView;
    }  

    // Atualiza o valor do Text para o nome do produto
    TextView textNome = (TextView) v.findViewById(R.id.nome);
    textNome.setText(p.getNome());

    return v;
}

另外,请记住将inflater声明为字段。

LayoutInflater inflater = null;

并在构造函数中初始化它。

public PropriedadeAdapter(Context context, List<Propriedades> prop) {
    this.context = context;
    this.prop = prop;
    inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

以上是关于滚动时,Android Listview重置更改的主要内容,如果未能解决你的问题,请参考以下文章

方向/配置更改后如何维护 ListView 片段状态?

在我的 android 应用程序中滚动列表视图时,数据正在消失。我在片段中使用列表视图

SwiftUI List 在任何视图更改时重置滚动

Android - 在 ListView 中滚动时滚动出/折叠元素

如何更改 Android ListView 分隔线的颜色?

ListView 在滚动时不会更改元素