TextView в строках списка, показывающих повторяющиеся значения при прокрутке в Android?

Я работаю с пользовательским адаптером ListView, в котором у меня есть TextView и Spinner. После выбора значений из счетчика значение после копирования в TextView соответствующей строки списка.

Проблема в том, что у меня более 40 элементов в ListView , когда я выбираю первый счетчик и устанавливаю значение для соответствующего TextView, при прокрутке одно и то же значение отображается в 10-м ряду TextView.

Значения копируются из 1-го TextView в 10-е TextView при прокрутке.

Ниже приведен код, который я использую:

public class AppListAdapter extends BaseAdapter {

    private LayoutInflater mInflater;
    private List<App> mApps = Constants.list;
    private Context _activity;
    ArrayList<String> months=null;
    ArrayAdapter<String> dataAdapter =null;
    int spinerposition;
    int viewposition;

    int temp=0;
    private int screenWidth;


    /**
     * Constructor.
     * 
     * @param context the application context which is needed for the layout inflater
     * @param screenWidth 
     */
    public AppListAdapter(Context context, int screenWidth) {
        // Cache the LayoutInflate to avoid asking for a new one each time.
        mInflater = LayoutInflater.from(context);
        this._activity=context;
        this.screenWidth = screenWidth;

        months = new ArrayList<String>();
        months.add("No Item Selected");
        months.add("None");
        months.add("Entertainment");
        months.add("Games");
        months.add("News/Books");
        months.add("Social Networking");
        months.add("Utilities");
        months.add("Texting");
        months.add("Web Browsers");


        // Creating adapter for spinner
        dataAdapter = new ArrayAdapter<String>(_activity,
                android.R.layout.simple_spinner_item, months);

        // Drop down layout style - list view with radio button
        dataAdapter.setDropDownViewResource(android.R.layout.select_dialog_singlechoice);


    }

    public int getCount() {

        return mApps.size();
    }

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

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

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

        final AppViewHolder holder;

        viewposition=position;
        if(convertView == null) {
            convertView = mInflater.inflate(R.layout.row, null);
            // creates a ViewHolder and stores a reference to the children view we want to bind data to
            holder = new AppViewHolder();

            holder.spiner=(Spinner)convertView.findViewById(R.id.spinner);
            holder.offtext=(TextView)convertView.findViewById(R.id.off_txt);


            holder.offTxt = (TextView) convertView.findViewById(R.id.off_txt);
            holder.apptitleTxt = (TextView) convertView.findViewById(R.id.apptitle_txt);
            Typeface typeface = Typeface.createFromAsset(_activity.getAssets(),"CHICM___.TTF");
            holder.apptitleTxt.setTypeface(typeface);
            holder.offTxt.setTypeface(typeface);

            if(screenWidth>480){
                holder.offTxt.setTextSize(30);
                holder.apptitleTxt.setTextSize(30);
            }
            convertView.setTag(holder);
        } else { 
            holder = (AppViewHolder) convertView.getTag();
        }

        holder.setTitle(mApps.get(position).getTitle(),mApps.get(position).getVersionName());

        notifyDataSetChanged();

        holder.offTxt.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                holder.spiner.performClick();

            }
        });

        holder.spiner.setAdapter(dataAdapter);
        holder.spiner.setOnItemSelectedListener(new OnItemSelectedListener() {
            public void onItemSelected(AdapterView<?> arg0, View arg1,int arg2, long arg3) {
                spinerposition=arg2;
                switch (spinerposition)
                {
                case 1:

                    holder.offtext.setText("None");
                    break;
                case 2:

                    holder.offtext.setText("Entertainment");
                    break;
                case 3:

                    holder.offtext.setText("Games");
                    break;
                case 4:

                    holder.offtext.setText("News/Books");
                    break;
                case 5:

                    holder.offtext.setText("Social Networking");
                    break;
                case 6:

                    holder.offtext.setText("Utilities");
                    break;
                case 7:

                    holder.offtext.setText("Texting");
                    break;
                case 8:

                    holder.offtext.setText("Web Browsers");
                    break;
                }
            }
            public void onNothingSelected(AdapterView<?> arg0) {
            }
        });
        return convertView; 
    }



    /**
     * Sets the list of apps to be displayed.
     * 
     * @param list the list of apps to be displayed
     */
    public void setListItems(List<App> list) { 
        mApps = list; 
    }

    /**
     * A view holder which is used to re/use views inside a list.
     */
    public class AppViewHolder {

        private TextView mTitle = null;
        private TextView apptitleTxt = null;
        private TextView offTxt = null;
        private Spinner spiner=null;
        public TextView offtext;
        /**
         * Sets the text to be shown as the app's title
         * 
         * @param title the text to be shown inside the list row
         */
        public void setTitle(String title,String category) {
            apptitleTxt.setText(title);
//          offtext.setText(category);
        }
    }

}

person Sam-In-TechValens    schedule 17.06.2013    source источник
comment
Заголовок дляholder.offtext устанавливается неправильно? Если это так, я не вижу ваш заголовок каждый раз, когда вы входите в метод getView. Вы делаете это только в своем OnItemSelectedListener. Из-за чего он будет показывать устаревшие данные в какое-то время.   -  person Jayshil Dave    schedule 17.06.2013
comment
взгляните на мой взгляд повторяется каждый 6-й элемент"> stackoverflow.com/questions/6470089/   -  person Sam    schedule 27.01.2017


Ответы (3)


Это связано с тем, что ListView повторно использует все предыдущие Views, которые прокручиваются (не видны).

Ознакомьтесь с этой темой.

person Dmytro Danylyk    schedule 17.06.2013
comment
Да ... Я закончил с этой проблемой ... получил огромные знания о свойствах представления списка. кстати спасибо. - person Sam-In-TechValens; 28.03.2014

Изменять

   if(convertView == null) {
            convertView = mInflater.inflate(R.layout.row, null);
            // creates a ViewHolder and stores a reference to the children view we want to bind data to
            holder = new AppViewHolder();

            holder.spiner=(Spinner)convertView.findViewById(R.id.spinner);
            holder.offtext=(TextView)convertView.findViewById(R.id.off_txt);


            holder.offTxt = (TextView) convertView.findViewById(R.id.off_txt);
            holder.apptitleTxt = (TextView) convertView.findViewById(R.id.apptitle_txt);
            Typeface typeface = Typeface.createFromAsset(_activity.getAssets(),"CHICM___.TTF");
            holder.apptitleTxt.setTypeface(typeface);
            holder.offTxt.setTypeface(typeface);

            if(screenWidth>480){
                holder.offTxt.setTextSize(30);
                holder.apptitleTxt.setTextSize(30);
            }
            convertView.setTag(holder);
        } else { 
            holder = (AppViewHolder) convertView.getTag();
        }

TO

convertView = mInflater.inflate(R.layout.row, null);
    // creates a ViewHolder and stores a reference to the children view we want to bind data to
    holder = new AppViewHolder();

    holder.spiner=(Spinner)convertView.findViewById(R.id.spinner);
    holder.offtext=(TextView)convertView.findViewById(R.id.off_txt);


    holder.offTxt = (TextView) convertView.findViewById(R.id.off_txt);
    holder.apptitleTxt = (TextView) convertView.findViewById(R.id.apptitle_txt);
    Typeface typeface = Typeface.createFromAsset(_activity.getAssets(),"CHICM___.TTF");
    holder.apptitleTxt.setTypeface(typeface);
    holder.offTxt.setTypeface(typeface);

    if(screenWidth>480){
        holder.offTxt.setTextSize(30);
        holder.apptitleTxt.setTextSize(30);
    }
    convertView.setTag(holder);

Теперь вы можете видеть, что все будет работать правильно. Это не лучший способ решить проблему! Необходимо управлять состоянием ваших элементов при использовании преобразования представления для повторного использования представления.

РЕДАКТИРОВАТЬ

public class AppListAdapter extends BaseAdapter {

    private LayoutInflater mInflater;
    private List<App> mApps = Constants.list;
    private Context _activity;
    ArrayList<String> months=null;
    ArrayAdapter<String> dataAdapter =null;
    int spinerposition;
    int viewposition;

    int temp=0;
    private int screenWidth;


     ArrayList<String> vals=null;


    /**
     * Constructor.
     * 
     * @param context the application context which is needed for the layout inflater
     * @param screenWidth 
     */
    public AppListAdapter(Context context, int screenWidth) {
        // Cache the LayoutInflate to avoid asking for a new one each time.
        mInflater = LayoutInflater.from(context);
        this._activity=context;
        this.screenWidth = screenWidth;

        months = new ArrayList<String>();
        months.add("No Item Selected");
        months.add("None");
        months.add("Entertainment");
        months.add("Games");
        months.add("News/Books");
        months.add("Social Networking");
        months.add("Utilities");
        months.add("Texting");
        months.add("Web Browsers");

        vals = new ArrayList<String>();


        // Creating adapter for spinner
        dataAdapter = new ArrayAdapter<String>(_activity,
                android.R.layout.simple_spinner_item, months);

        // Drop down layout style - list view with radio button
        dataAdapter.setDropDownViewResource(android.R.layout.select_dialog_singlechoice);


    }

    public int getCount() {

        return mApps.size();
    }

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

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

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

        final AppViewHolder holder;

        viewposition=position;

            convertView = mInflater.inflate(R.layout.row, null);
            // creates a ViewHolder and stores a reference to the children view we want to bind data to
            holder = new AppViewHolder();

            holder.spiner=(Spinner)convertView.findViewById(R.id.spinner);
            holder.offtext=(TextView)convertView.findViewById(R.id.off_txt);


            holder.offTxt = (TextView) convertView.findViewById(R.id.off_txt);
            holder.apptitleTxt = (TextView) convertView.findViewById(R.id.apptitle_txt);
            Typeface typeface = Typeface.createFromAsset(_activity.getAssets(),"CHICM___.TTF");
            holder.apptitleTxt.setTypeface(typeface);
            holder.offTxt.setTypeface(typeface);

            if(screenWidth>480){
                holder.offTxt.setTextSize(30);
                holder.apptitleTxt.setTextSize(30);
            }
            convertView.setTag(holder);


if(vals.get(position)!=null)
{
 holder.offtext.setText(vals.get(position));
}


        holder.setTitle(mApps.get(position).getTitle(),mApps.get(position).getVersionName());

        notifyDataSetChanged();

        holder.offTxt.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                holder.spiner.performClick();

            }
        });

        holder.spiner.setAdapter(dataAdapter);
        holder.spiner.setOnItemSelectedListener(new OnItemSelectedListener() {
            public void onItemSelected(AdapterView<?> arg0, View arg1,int arg2, long arg3) {
                spinerposition=arg2;
                switch (spinerposition)
                {
                case 1:

                    holder.offtext.setText("None");
                    break;
                case 2:

                    holder.offtext.setText("Entertainment");
                    break;
                case 3:

                    holder.offtext.setText("Games");
                    break;
                case 4:

                    holder.offtext.setText("News/Books");
                    break;
                case 5:

                    holder.offtext.setText("Social Networking");
                    break;
                case 6:

                    holder.offtext.setText("Utilities");
                    break;
                case 7:

                    holder.offtext.setText("Texting");
                    break;
                case 8:

                    holder.offtext.setText("Web Browsers");
                    break;
                }
         vals.add(arg2,holder.offtext.getText());
            }
            public void onNothingSelected(AdapterView<?> arg0) {
            }
        });
        return convertView; 
    }



    /**
     * Sets the list of apps to be displayed.
     * 
     * @param list the list of apps to be displayed
     */
    public void setListItems(List<App> list) { 
        mApps = list; 
    }

    /**
     * A view holder which is used to re/use views inside a list.
     */
    public class AppViewHolder {

        private TextView mTitle = null;
        private TextView apptitleTxt = null;
        private TextView offTxt = null;
        private Spinner spiner=null;
        public TextView offtext;
        /**
         * Sets the text to be shown as the app's title
         * 
         * @param title the text to be shown inside the list row
         */
        public void setTitle(String title,String category) {
            apptitleTxt.setText(title);
//          offtext.setText(category);
        }
    }

}
person Arun C    schedule 17.06.2013
comment
Я внес изменения, но всякий раз, когда я прокручиваю вниз и обратно вверх, значение повторно инициализируется до None. - person Sam-In-TechValens; 17.06.2013
comment
Вам нужно сохранить значения в список массивов или где-то еще, а затем восстановить его getView() в текстовом виде offTxt. - person Arun C; 17.06.2013
comment
Он все еще не работает ... Во-первых, у меня был сбой в Arraylist, после обработки сбоя проблема остается прежней. - person Sam-In-TechValens; 17.06.2013

Я получил решение проблемы. Я представил dialogList(), в котором я работаю с ArrayList. Ниже я упомянул код моего класса адаптера.

public class AppListAdapter extends BaseAdapter {

    private LayoutInflater mInflater;
    private List<App> mApps = Constants.list;
    private Context _activity;
    ArrayList<String> months=null;
    ArrayAdapter<String> dataAdapter =null;
    int spinerposition;
    Context contextfordatabase=null;

    int temp=0;
    private int screenWidth;


    /**
     * Constructor.
     * 
     * @param context the application context which is needed for the layout inflater
     * @param screenWidth 
     */
    public AppListAdapter(Context context, int screenWidth) {
        contextfordatabase=context;
        // Cache the LayoutInflate to avoid asking for a new one each time.
        mInflater = LayoutInflater.from(context);
        this._activity=context;
        this.screenWidth = screenWidth;

        months = new ArrayList<String>();
        months.add("No Item Selected");
        months.add("None");
        months.add("Entertainment");
        months.add("Games");
        months.add("News/Books");
        months.add("Social Networking");
        months.add("Utilities");
        months.add("Texting");
        months.add("Web Browsers");
    }

    public int getCount() {

        return mApps.size();
    }

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

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

    public class AppViewHolder {

        private TextView mTitle = null;
        private TextView apptitleTxt = null;
        private TextView offTxt = null;
        private Spinner spiner=null;
        public TextView offtext;
    }

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

        final AppViewHolder holder;
        if(convertView == null) {
            convertView = mInflater.inflate(R.layout.row, null);
            // creates a ViewHolder and stores a reference to the children view we want to bind data to
            holder = new AppViewHolder();

            holder.spiner=(Spinner)convertView.findViewById(R.id.spinner);
            holder.offtext=(TextView)convertView.findViewById(R.id.off_txt);

            holder.apptitleTxt = (TextView) convertView.findViewById(R.id.apptitle_txt);
            Typeface typeface = Typeface.createFromAsset(_activity.getAssets(),"CHICM___.TTF");
            holder.apptitleTxt.setTypeface(typeface);
            holder.offtext.setTypeface(typeface);

            if(screenWidth>480){
                holder.offtext.setTextSize(30);
                holder.apptitleTxt.setTextSize(30);
            }
            convertView.setTag(holder);
        } else { 
            holder = (AppViewHolder) convertView.getTag();
        }

        holder.offtext.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                dialogList(holder.offtext, position);
            }
        });

        holder.apptitleTxt.setText(mApps.get(position).getTitle());
        holder.offtext.setText(mApps.get(position).getVersionName());

        return convertView; 
    }

    /**
     * Sets the list of apps to be displayed.
     * 
     * @param list the list of apps to be displayed
     */
    public void setListItems(List<App> list) { 
        mApps = list; 
    }

    public void dialogList(final TextView textView, final int clickedPosition){
        Builder builder = new AlertDialog.Builder(_activity);
        builder.setTitle("Select Category");
        builder.setItems(R.array.category_list, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) 
            {
                textView.setText(months.get(which+1));
                App app = new App();
                app.setTitle(mApps.get(clickedPosition).getTitle());
                app.setPackageName(mApps.get(clickedPosition).getPackageName());
                app.setVersionName(months.get(which+1));
                app.setVersionCode(mApps.get(clickedPosition).getVersionCode());
                mApps.set(clickedPosition, app);
                System.out.println(clickedPosition+" : "+months.get(which+1));


                update_database(mApps.get(clickedPosition).getPackageName(),months.get(which+1));


                AppListAdapter.this.notifyDataSetChanged();
            }

        });
        builder.create();
        builder.show();
    }

    public void update_database(String packageName, String string) {
        CallBackDatabase callback = new CallBackDatabase(contextfordatabase);
        callback.open();
        Cursor cursor =callback.getAll(packageName);
        int y=cursor.getCount();
        int j=0;
        if(y!=0)
        {
            callback.UpdateCategory(packageName, string);
        }
        else
        {
            callback.InsertAppInfo(null, packageName, "0", "0", "0", "null", string);
        }
        cursor.deactivate();
        cursor.close();
        callback.close();
    }

}
person Sam-In-TechValens    schedule 18.06.2013
comment
Спасибо, Сэм, я тоже столкнулся с этой проблемой. Это помогло мне избавиться от этой проблемы. - person Pawan Gupta; 18.06.2013