ListView未从异步刷新(布局可能有问题)



我正在编写我的第一个应用程序,无法从Async类正确更新Listview。当自定义适配器最初创建时,我可以用信息填充它,但当我尝试更新内容时,列表视图只会变为空白。如果我转动手机,新内容会出现一秒钟,但随后会再次消失。

主要活动:

public class SearchBooksActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener, OnItemSelectedListener {
ListView listView;
TextView pageNumbers;
private Spinner dropdown;
private String[] items = new String[]{"- Select the genre -", "Adventure", "Children", "Comedy",
"Fairy tales", "Fantasy", "Fiction", "Historical Fiction", "History", "Humor",
"Literature", "Mystery", "Non-fiction", "Philosophy", "Poetry", "Romance", "Religion",
"Science fiction", "Short stories", "Teen/Young adult"};
//ArrayLists used to store links to book names, their thumbnails to be passed
//into CustomAdapterListView
private List<BookListView> books = new ArrayList<>();
public ArrayList<String> pageNumber= new ArrayList<String>();
CustomAdapterListView mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search_books);
dropdown = (Spinner) findViewById(R.id.spinner1);
ArrayAdapter<String> adapter = new ArrayAdapter<>(this,
android.R.layout.simple_spinner_dropdown_item, items);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
dropdown.setAdapter(adapter);
dropdown.setOnItemSelectedListener(this);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
listView = (ListView) findViewById(R.id.listView);
pageNumbers = (TextView) findViewById(R.id.pageView);
}
public void RunAsyncPageParser(String url) {
Toast.makeText(this, "Loading...Wait...", Toast.LENGTH_SHORT).show();
FillListViev2 fillListViev = new FillListViev2(url);
fillListViev.execute();
}
public void onItemSelected(AdapterView<?> parent, View v, int position, long id) {
switch (position) {
case 0:
RunAsyncPageParser("http://www.loyalbooks.com/Top_100");
break;
case 1:
RunAsyncPageParser("http://www.loyalbooks.com/genre/Adventure");
break;
case 2:
RunAsyncPageParser("http://www.loyalbooks.com/genre/Children");
break;
case 3:
RunAsyncPageParser("http://www.loyalbooks.com/genre/Comedy");
break;
...
}
public void onNothingSelected(AdapterView<?> parent) {
}
@Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}

@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.browse_books) {
Toast.makeText(this, "TEST", Toast.LENGTH_SHORT).show();
} else if (id == R.id.offline_books) {
} else if (id == R.id.settings) {
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
@Override
protected void onDestroy() {
super.onDestroy();
}
public class FillListViev2 extends AsyncTask<Void, Void, List<BookListView>> {
//site url to be passed into consructor
private String site;

public FillListViev2(String title) {
this.site = title;
}
@Override
protected List<BookListView> doInBackground(Void... params) {
//parsed doc will be stored in this field
Document doc = null;
//fields to store raw html lines used to extract book names, their thumbnails
// as well as number of total pages of the books category
Elements mLines;
Elements mLines2;
try {
//connect to the site
doc = Jsoup.connect(site).get();
} catch (IOException | RuntimeException e) {
e.printStackTrace();
}
if (doc != null) {
// getting all elements with classname "layout"
mLines = doc.getElementsByClass("layout");
//searching for book names and their thumbnails and adding them to ArrayLists
for (Element mLine : mLines) {
String mPic = mLine.attr("src");
String mName = mLine.attr("alt");
books.add(new BookListView(mName,"http://www.loyalbooks.com" + mPic));

}
// getting all elements with tag "ul"
mLines2 = doc.getElementsByTag("ul");
//searching for total number of pages in category and adding it to ArrayList
for (Element mLine2 : mLines2) {
String mPages = mLine2.text();
pageNumber.add(mPages);
}
}else
System.out.println("ERROR");
return books;
}
protected void onPostExecute(List<BookListView> books) {
super.onPostExecute(books);

if (books.size() > 0) {
try {
if (listView.getAdapter() != null){
mAdapter.clear();
mAdapter.addAll(books);
Toast.makeText(SearchBooksActivity.this, "TEST", Toast.LENGTH_SHORT).show();
} else {
mAdapter = new CustomAdapterListView(SearchBooksActivity.this,
R.layout.search_books_listview_item, books);
listView.setAdapter(mAdapter);
}
pageNumbers.setText(pageNumber.get(0).substring(10, pageNumber.get(0).length() -2));
} catch(RuntimeException e) {
e.printStackTrace();
}
} else Toast.makeText(SearchBooksActivity.this, "NETWORK ERROR", Toast.LENGTH_LONG).show();
}
}

Pojo类:

public class BookListView {
private String title;
private String imageUrl;
public BookListView(String title, String imageUrl) {
this.title = title;
this.imageUrl = imageUrl;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}

适配器类别:

public class CustomAdapterListView extends ArrayAdapter<BookListView> {
private Context mContext;
private List<BookListView> books;
private int resource;
public CustomAdapterListView(Context context, int resource, List<BookListView> objects) {
super(context, resource, objects);
this.mContext = context;
this.resource = resource;
this.books = objects;
}
public int getCount() {
return books.size();
}
public BookListView getItem(int arg0) {
return books.get(arg0);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = LayoutInflater.from(mContext).inflate(resource, parent, false);
holder = new ViewHolder();
holder.title = convertView.findViewById(R.id.title);
holder.i1 = convertView.findViewById(R.id.imageViewLstRow);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
BookListView item = getItem(position);
Picasso.get().load(item.getImageUrl()).resize(80, 80).centerCrop().into(holder.i1);
holder.title.setText(item.getTitle());
return convertView;
}
class ViewHolder {
public TextView title;
public ImageView i1;
}

我不认为问题出在适配器本身,因为它有点工作,并且onPostExecute方法中的这一行在我旋转设备之前不会更新Textview。

pageNumbers.setText(pageNumber.get(0).substring(10, pageNumber.get(0).length() -2));

首先创建一个像这样的pojo类,

public class Book {
private String title;
private String imageUrl;
public Book(String title, String imageUrl) {
this.title = title;
this.imageUrl = imageUrl;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
}

然后从你的活动中删除这些

public ArrayList<String> titleList = new ArrayList<String>();
public ArrayList<String> imgList = new ArrayList<String>();

将异步任务更改为,

public class FillListViev2 extends AsyncTask<Void, Void, List<Book>> {
//site url to be passed into consructor
private String site;
private List<Book> books = new ArrayList<>();
private ArrayList<String> pageNumber = new ArrayList<>();

public FillListViev2(String title) {
this.site = title;
}
@Override
protected List<Book> doInBackground(Void... params) {
//parsed doc will be stored in this field
Document doc = null;
//fields to store raw html lines used to extract book names, their thumbnails
// as well as number of total pages of the books category
Elements mLines;
Elements mLines2;
try {
//connect to the site
doc = Jsoup.connect(site).get();
} catch (IOException | RuntimeException e) {
e.printStackTrace();
}
if (doc != null) {
// getting all elements with classname "layout"
mLines = doc.getElementsByClass("layout");
//searching for book names and their thumbnails and adding them to ArrayLists
for (Element mLine : mLines) {
String mPic = mLine.attr("src");
String mName = mLine.attr("alt");
books.add(new Book(mName, mPic));
}
// getting all elements with tag "ul"
mLines2 = doc.getElementsByTag("ul");
//searching for total number of pages in category and adding it to ArrayList
for (Element mLine2 : mLines2) {
String mPages = mLine2.text();
pageNumber.add(mPages);
}
} else
System.out.println("ERROR");
return books;
}
@Override
protected void onPostExecute(List<Book> books) {
super.onPostExecute(books);
if (books.size() > 0) {
try {
if (listView.getAdapter() != null) {
mAdapter.clear();
mAdapter.addAll(books);
Toast.makeText(SearchBooksActivity.this, "TEST", Toast.LENGTH_SHORT).show();
} else {
mAdapter = new CustomAdapterListView(SearchBooksActivity.this, R.layout.search_books_listview_item, books);
listView.setAdapter(mAdapter);
}
pageNumbers.setText(pageNumber.get(0).substring(10, pageNumber.get(0).length() - 2));
} catch (RuntimeException e) {
e.printStackTrace();
}
} else
Toast.makeText(SearchBooksActivity.this, "NETWORK ERROR", Toast.LENGTH_LONG).show();
}
}

和您的适配器,

public class CustomAdapterListView extends ArrayAdapter<Book> {
private Context mContext;
private List<Book> books;
private int resource;
public CustomAdapterListView(Context context, int resource, List<Book> objects) {
super(context, resource, objects);
this.mContext = context;
this.resource = resource;
this.books = objects;
}
public int getCount() {
return books.size();
}
public Book getItem(int arg0) {
return books.get(arg0);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = LayoutInflater.from(mContext).inflate(resource, parent, false);
holder = new ViewHolder();
holder.title = (TextView) convertView.findViewById(R.id.title);
holder.i1 = (ImageView) convertView.findViewById(R.id.imageViewLstRow);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Book item = getItem(position);
Picasso.get().load(item.getImageUrl()).resize(80, 80).centerCrop().into(holder.i1);
holder.title.setText(item.getTitle());
return convertView;
}
class ViewHolder {
private TextView title;
private ImageView i1;
}
}

尝试更改此代码。。

else {
if (adapter!=null){
mAdapter = new CustomAdapterListView(SearchBooksActivity.this,
titleList, imgList);
listView.setAdapter(mAdapter);
}else{
adapter.notifyDataSetChanged();
}
}

您确定mAdapter确实是连接到您的listView的适配器吗?也许你可以查一下:

if (listView.getAdapter() != null && listView.getAdapter() == mAdapter){

最新更新