7

我正在使用 ListView 的自定义适配器,其中有一个 TextView 和一个 Spinner。从 Spinner 中选择值后,将值复制到列表的相应同一行的 TextView 后。

问题是,由于我在 ListView 中有 40 多个元素,当我选择第一个微调器并将值设置为相应的 TextView 时,在滚动时,在第 10 行 TextView 中会看到相同的值。

滚动时将值从第一个 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);
        }
    }

}
4

3 回答 3

2

这是因为ListView正在重用所有以前Views滚动的(不可见)。

请查看主题。

于 2013-06-17T07:23:22.473 回答
1

改变

   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();
        }

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);
        }
    }

}
于 2013-06-17T07:24:30.097 回答
0

我得到了这个问题的解决方案。我介绍了一个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();
    }

}
于 2013-06-18T07:16:59.423 回答