我正在使用ListView的自定义适配器,其中我有一个TextView和一个Spinner。从Spinner中选择值后,将该值复制到相应行列表的TextView之后。
问题是,由于我在ListView中有超过40个元素,当我选择第一个微调器并将值设置为相应的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);
}
}
}
答案 0 :(得分:1)
这是因为ListView
正在重复使用滚动(不可见)的所有先前的Views
。
请查看this主题。
答案 1 :(得分: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);
}
}
}
答案 2 :(得分:0)
我得到了问题的解决方案。我已经介绍了一个dialogList()
,我正在使用ArrayList。下面我提到了我的Adapter类的代码。
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();
}
}