Convert View always return null 而不是回收
Convert View always return null instead of recycling
我有3个碎片,分别是"Home"、"Shop"和"Collection"。在 Collection 片段中执行 DownloadTask 后,进度条和文本视图正在更新。但是一旦我 select 编辑主页选项卡(第一个选项卡)并 select 返回 Collection 选项卡(第三个选项卡),视图将被重新创建而不是回收,这意味着进度和文本视图恢复到它的默认状态。
原因可能是转换视图,因为它不断返回空值并创建新视图。但我不知道为什么它一直返回 null。希望任何人都可以提供帮助。
package com.GempakStarz.GempakMagazine
public class CollectionListAdapter extends BaseAdapter implements
OnClickListener {
private Context context;
private Activity parentActivity;
private String[] books;
private Map<String, Button> downloadbuttons = new HashMap<String, Button>();
private Map<String, Button> deletebuttons = new HashMap<String, Button>();
private Map<String, ProgressBar> progressbars = new HashMap<String, ProgressBar>();
private Map<String, TextView> progress_texts = new HashMap<String, TextView>();
public CollectionListAdapter(Context context, Activity parentActivity,
String[] books) {
this.context = context;
this.books = books;
this.parentActivity = parentActivity;
}
@Override
public int getCount() {
return books.length;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
Log.v("Check", "ConvertViewCreated!");
String bookname = books[position];
convertView = new View(context);
convertView = inflater.inflate(R.layout.collection_list_item, null);
TextView textView = (TextView) convertView.findViewById(R.id.title);
textView.setText(bookname.replace("gempak", "G"));
// set image based on selected text
ImageView imageView = (ImageView) convertView.findViewById(R.id.image);
imageView.setImageResource(R.drawable.ic_launcher);
Button download_button = (Button) convertView
.findViewById(R.id.download);
download_button.setTag(bookname);
download_button.setOnClickListener(this);
Button delete_button = (Button) convertView.findViewById(R.id.delete);
delete_button.setTag(bookname);
delete_button.setOnClickListener(this);
RelativeLayout view = (RelativeLayout) convertView
.findViewById(R.id.background);
view.setTag(bookname);
view.setOnClickListener(this);
ProgressBar progressbar = (ProgressBar) convertView
.findViewById(R.id.progressBar1);
TextView progress_text = (TextView) convertView
.findViewById(R.id.text_progress);
downloadbuttons.put(bookname, download_button);
deletebuttons.put(bookname, delete_button);
progressbars.put(bookname, progressbar);
progress_texts.put(bookname, progress_text);
if (DownloadCompleted(bookname)) {
downloadbuttons.get(bookname).setEnabled(false);
download_button.setText("Download");
progressbars.get(bookname).setProgress(100);
progress_texts.get(bookname).setText("Download Complete");
} else {
Log.v("LOL", "Not in Storage");
}
} else {
Log.v("Check", "ConvertViewReused!!!");
}
return convertView;
}
public boolean DownloadCompleted(String bookname) {
if (Book.getInstance() != null) {
int pagenumber = Book.getInstance().GetBookLibrary().get(bookname).max_page;
int saved_files = 0;
for (int i = 0; i < pagenumber; i++) {
String foldername = bookname;
String filename = "page" + i;
String filepath = Environment.getExternalStorageDirectory()
.getPath() + "/" + foldername + "/" + filename + ".jpg";
File f = new File(Environment.getExternalStorageDirectory(),
foldername);
if (!f.exists()) {
f.mkdirs();// create new directory
}
File fpath = new File(filepath);
if (fpath.exists()) {
saved_files += 1;
}
}
if (saved_files == pagenumber) {
return true;
} else {
return false;
}
}
return false;
}
String checkInternetStatus() {
final ConnectivityManager connMgr = (ConnectivityManager) parentActivity
.getSystemService(Context.CONNECTIVITY_SERVICE);
final android.net.NetworkInfo wifi = connMgr
.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
final android.net.NetworkInfo mobile = connMgr
.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if (wifi.isAvailable()) {
return "Wifi";
} else if (mobile.isAvailable()) {
return "Data";
} else {
return "None";
}
}
@Override
public void onClick(View v) {
final String bookname = v.getTag().toString();
final DownloadTask task = new DownloadTask(context, v.getTag()
.toString(), progressbars.get(bookname),
downloadbuttons.get(bookname), deletebuttons.get(bookname),
progress_texts.get(bookname));
switch (v.getId()) {
case R.id.download:
if (checkInternetStatus() == "Wifi") {
if (Book.getInstance() != null) {
Toast.makeText(
context,
"Download : "
+ Book.getInstance().GetBookLibrary()
.get(bookname).name,
Toast.LENGTH_SHORT).show();
task.execute(Book.getInstance().GetDownloadLinks(bookname));
} else {
Toast.makeText(context, "Error", Toast.LENGTH_SHORT).show();
}
} else if (checkInternetStatus() == "Data") {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
parentActivity);
alertDialogBuilder
.setMessage("You are using mobile data right now, continue download with mobile data? ");
alertDialogBuilder.setTitle("" + bookname);
alertDialogBuilder.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
if (Book.getInstance() != null) {
Toast.makeText(
context,
"Download : "
+ Book.getInstance()
.GetBookLibrary()
.get(bookname).name,
Toast.LENGTH_SHORT).show();
task.execute(Book.getInstance()
.GetDownloadLinks(bookname));
} else {
Toast.makeText(context, "Error",
Toast.LENGTH_SHORT).show();
}
}
});
alertDialogBuilder.setNegativeButton("No",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
} else {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
parentActivity);
alertDialogBuilder.setMessage("No Internet Access ");
alertDialogBuilder.setTitle("System Message");
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
break;
case R.id.delete:
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
parentActivity);
alertDialogBuilder.setMessage("Delete " + bookname + "?");
alertDialogBuilder.setTitle("" + bookname);
alertDialogBuilder.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
Toast.makeText(context, bookname + " Deleted",
Toast.LENGTH_SHORT).show();
task.cancel(true);
task.DeleteAll(bookname);
}
});
alertDialogBuilder.setNegativeButton("No",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
break;
case R.id.background:
if (DownloadCompleted(v.getTag().toString())) {
Intent read_view = new Intent(context, ReadViewPager.class);
read_view.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
read_view.putExtra("Bookname", v.getTag().toString());
read_view.putExtra("PageNumber", 153);
context.startActivity(read_view);
}
break;
}
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
}
只需更新此:
convertView = inflater.inflate(R.layout.collection_list_item, parent, false);
并删除这个:
convertView = new View(context);
并致电:
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
里面if(convertView==null){...
But once I selected the Home tab(1st tab) and select back the
Collection tab(3rd tab) the views is recreated instead of recycling
which means the progress and textview restore to its default state.
你错了。您总是返回相同的 convertView,即您第一次初始化的那个,当 convertView 为 null 时,没有更改的是值。必须在 if/else
守卫之外执行将值分配给您的视图。例如
if (convertView == null) {
// inflate convertView
}
// convertView.findViewById
// retrieve it the item at position in your dataset
// assign values to the views
对于您的情况,您需要将 getView
更改为:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
Log.v("Check", "ConvertViewCreated!");
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.collection_list_item, null);
} else {
Log.v("Check", "ConvertViewReused!!!");
}
String bookname = books[position];
TextView textView = (TextView) convertView.findViewById(R.id.title);
textView.setText(bookname.replace("gempak", "G"));
// set image based on selected text
ImageView imageView = (ImageView) convertView.findViewById(R.id.image);
imageView.setImageResource(R.drawable.ic_launcher);
Button download_button = (Button) convertView
.findViewById(R.id.download);
download_button.setTag(bookname);
download_button.setOnClickListener(this);
Button delete_button = (Button) convertView.findViewById(R.id.delete);
delete_button.setTag(bookname);
delete_button.setOnClickListener(this);
RelativeLayout view = (RelativeLayout) convertView
.findViewById(R.id.background);
view.setTag(bookname);
view.setOnClickListener(this);
ProgressBar progressbar = (ProgressBar) convertView
.findViewById(R.id.progressBar1);
TextView progress_text = (TextView) convertView
.findViewById(R.id.text_progress);
downloadbuttons.put(bookname, download_button);
deletebuttons.put(bookname, delete_button);
progressbars.put(bookname, progressbar);
progress_texts.put(bookname, progress_text);
if (DownloadCompleted(bookname)) {
downloadbuttons.get(bookname).setEnabled(false);
download_button.setText("Download");
progressbars.get(bookname).setProgress(100);
progress_texts.get(bookname).setText("Download Complete");
} else {
Log.v("LOL", "Not in Storage");
}
return convertView;
}
然后,我不认为这些代码是最好的编码规则。我向你推荐ViewHolder
方式。
我有3个碎片,分别是"Home"、"Shop"和"Collection"。在 Collection 片段中执行 DownloadTask 后,进度条和文本视图正在更新。但是一旦我 select 编辑主页选项卡(第一个选项卡)并 select 返回 Collection 选项卡(第三个选项卡),视图将被重新创建而不是回收,这意味着进度和文本视图恢复到它的默认状态。
原因可能是转换视图,因为它不断返回空值并创建新视图。但我不知道为什么它一直返回 null。希望任何人都可以提供帮助。
package com.GempakStarz.GempakMagazine
public class CollectionListAdapter extends BaseAdapter implements
OnClickListener {
private Context context;
private Activity parentActivity;
private String[] books;
private Map<String, Button> downloadbuttons = new HashMap<String, Button>();
private Map<String, Button> deletebuttons = new HashMap<String, Button>();
private Map<String, ProgressBar> progressbars = new HashMap<String, ProgressBar>();
private Map<String, TextView> progress_texts = new HashMap<String, TextView>();
public CollectionListAdapter(Context context, Activity parentActivity,
String[] books) {
this.context = context;
this.books = books;
this.parentActivity = parentActivity;
}
@Override
public int getCount() {
return books.length;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
Log.v("Check", "ConvertViewCreated!");
String bookname = books[position];
convertView = new View(context);
convertView = inflater.inflate(R.layout.collection_list_item, null);
TextView textView = (TextView) convertView.findViewById(R.id.title);
textView.setText(bookname.replace("gempak", "G"));
// set image based on selected text
ImageView imageView = (ImageView) convertView.findViewById(R.id.image);
imageView.setImageResource(R.drawable.ic_launcher);
Button download_button = (Button) convertView
.findViewById(R.id.download);
download_button.setTag(bookname);
download_button.setOnClickListener(this);
Button delete_button = (Button) convertView.findViewById(R.id.delete);
delete_button.setTag(bookname);
delete_button.setOnClickListener(this);
RelativeLayout view = (RelativeLayout) convertView
.findViewById(R.id.background);
view.setTag(bookname);
view.setOnClickListener(this);
ProgressBar progressbar = (ProgressBar) convertView
.findViewById(R.id.progressBar1);
TextView progress_text = (TextView) convertView
.findViewById(R.id.text_progress);
downloadbuttons.put(bookname, download_button);
deletebuttons.put(bookname, delete_button);
progressbars.put(bookname, progressbar);
progress_texts.put(bookname, progress_text);
if (DownloadCompleted(bookname)) {
downloadbuttons.get(bookname).setEnabled(false);
download_button.setText("Download");
progressbars.get(bookname).setProgress(100);
progress_texts.get(bookname).setText("Download Complete");
} else {
Log.v("LOL", "Not in Storage");
}
} else {
Log.v("Check", "ConvertViewReused!!!");
}
return convertView;
}
public boolean DownloadCompleted(String bookname) {
if (Book.getInstance() != null) {
int pagenumber = Book.getInstance().GetBookLibrary().get(bookname).max_page;
int saved_files = 0;
for (int i = 0; i < pagenumber; i++) {
String foldername = bookname;
String filename = "page" + i;
String filepath = Environment.getExternalStorageDirectory()
.getPath() + "/" + foldername + "/" + filename + ".jpg";
File f = new File(Environment.getExternalStorageDirectory(),
foldername);
if (!f.exists()) {
f.mkdirs();// create new directory
}
File fpath = new File(filepath);
if (fpath.exists()) {
saved_files += 1;
}
}
if (saved_files == pagenumber) {
return true;
} else {
return false;
}
}
return false;
}
String checkInternetStatus() {
final ConnectivityManager connMgr = (ConnectivityManager) parentActivity
.getSystemService(Context.CONNECTIVITY_SERVICE);
final android.net.NetworkInfo wifi = connMgr
.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
final android.net.NetworkInfo mobile = connMgr
.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if (wifi.isAvailable()) {
return "Wifi";
} else if (mobile.isAvailable()) {
return "Data";
} else {
return "None";
}
}
@Override
public void onClick(View v) {
final String bookname = v.getTag().toString();
final DownloadTask task = new DownloadTask(context, v.getTag()
.toString(), progressbars.get(bookname),
downloadbuttons.get(bookname), deletebuttons.get(bookname),
progress_texts.get(bookname));
switch (v.getId()) {
case R.id.download:
if (checkInternetStatus() == "Wifi") {
if (Book.getInstance() != null) {
Toast.makeText(
context,
"Download : "
+ Book.getInstance().GetBookLibrary()
.get(bookname).name,
Toast.LENGTH_SHORT).show();
task.execute(Book.getInstance().GetDownloadLinks(bookname));
} else {
Toast.makeText(context, "Error", Toast.LENGTH_SHORT).show();
}
} else if (checkInternetStatus() == "Data") {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
parentActivity);
alertDialogBuilder
.setMessage("You are using mobile data right now, continue download with mobile data? ");
alertDialogBuilder.setTitle("" + bookname);
alertDialogBuilder.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
if (Book.getInstance() != null) {
Toast.makeText(
context,
"Download : "
+ Book.getInstance()
.GetBookLibrary()
.get(bookname).name,
Toast.LENGTH_SHORT).show();
task.execute(Book.getInstance()
.GetDownloadLinks(bookname));
} else {
Toast.makeText(context, "Error",
Toast.LENGTH_SHORT).show();
}
}
});
alertDialogBuilder.setNegativeButton("No",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
} else {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
parentActivity);
alertDialogBuilder.setMessage("No Internet Access ");
alertDialogBuilder.setTitle("System Message");
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
break;
case R.id.delete:
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
parentActivity);
alertDialogBuilder.setMessage("Delete " + bookname + "?");
alertDialogBuilder.setTitle("" + bookname);
alertDialogBuilder.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
Toast.makeText(context, bookname + " Deleted",
Toast.LENGTH_SHORT).show();
task.cancel(true);
task.DeleteAll(bookname);
}
});
alertDialogBuilder.setNegativeButton("No",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
break;
case R.id.background:
if (DownloadCompleted(v.getTag().toString())) {
Intent read_view = new Intent(context, ReadViewPager.class);
read_view.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
read_view.putExtra("Bookname", v.getTag().toString());
read_view.putExtra("PageNumber", 153);
context.startActivity(read_view);
}
break;
}
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
}
只需更新此:
convertView = inflater.inflate(R.layout.collection_list_item, parent, false);
并删除这个:
convertView = new View(context);
并致电:
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
里面if(convertView==null){...
But once I selected the Home tab(1st tab) and select back the Collection tab(3rd tab) the views is recreated instead of recycling which means the progress and textview restore to its default state.
你错了。您总是返回相同的 convertView,即您第一次初始化的那个,当 convertView 为 null 时,没有更改的是值。必须在 if/else
守卫之外执行将值分配给您的视图。例如
if (convertView == null) {
// inflate convertView
}
// convertView.findViewById
// retrieve it the item at position in your dataset
// assign values to the views
对于您的情况,您需要将 getView
更改为:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
Log.v("Check", "ConvertViewCreated!");
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.collection_list_item, null);
} else {
Log.v("Check", "ConvertViewReused!!!");
}
String bookname = books[position];
TextView textView = (TextView) convertView.findViewById(R.id.title);
textView.setText(bookname.replace("gempak", "G"));
// set image based on selected text
ImageView imageView = (ImageView) convertView.findViewById(R.id.image);
imageView.setImageResource(R.drawable.ic_launcher);
Button download_button = (Button) convertView
.findViewById(R.id.download);
download_button.setTag(bookname);
download_button.setOnClickListener(this);
Button delete_button = (Button) convertView.findViewById(R.id.delete);
delete_button.setTag(bookname);
delete_button.setOnClickListener(this);
RelativeLayout view = (RelativeLayout) convertView
.findViewById(R.id.background);
view.setTag(bookname);
view.setOnClickListener(this);
ProgressBar progressbar = (ProgressBar) convertView
.findViewById(R.id.progressBar1);
TextView progress_text = (TextView) convertView
.findViewById(R.id.text_progress);
downloadbuttons.put(bookname, download_button);
deletebuttons.put(bookname, delete_button);
progressbars.put(bookname, progressbar);
progress_texts.put(bookname, progress_text);
if (DownloadCompleted(bookname)) {
downloadbuttons.get(bookname).setEnabled(false);
download_button.setText("Download");
progressbars.get(bookname).setProgress(100);
progress_texts.get(bookname).setText("Download Complete");
} else {
Log.v("LOL", "Not in Storage");
}
return convertView;
}
然后,我不认为这些代码是最好的编码规则。我向你推荐ViewHolder
方式。