问题的标题可能有点令人困惑,但作为初学者,我发现写一个准确的标题很难。现在我正在制作一个应用程序,从谷歌书籍api获取数据并在RecyclerView中显示它们。单击搜索按钮后,数据将加载到RecyclerView中。当我单击适配器的Individual Item时,它会打开DetailActivity。该应用程序正常工作如果我在MainActivity中旋转设备但是如果我在DetailActivity中旋转设备然后按回按钮,则MainActivity适配器为空。 MainActivity.java
package com.example.setha.booklisting;
import android.app.LoaderManager;
import android.content.Context;
import android.content.Intent;
import android.content.Loader;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<List<Books>> {
public static final String LOG_TAG = MainActivity.class.getName();
private static final int BOOKS_LOADER_ID = 1;
private static final String BOOK_LIST = "book in list";
private RecyclerView.Adapter adapter;
private RecyclerView recyclerView;
private TextView emptyView;
private List<Books> books_list;
private String book_searched = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i(LOG_TAG, "TEST: onCreate() called ...");
//calling adapter on a empty book list
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(false);
recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
adapter = new MyAdapter(new ArrayList<Books>());
recyclerView.setAdapter(adapter);
Button searchButton = (Button) findViewById(R.id.button_search);
searchButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.i(LOG_TAG, "TEST: search button clicked ...");
book_searched = getSearchTerm();
Log.i(LOG_TAG, "TEST: " + book_searched);
if (!book_searched.equals("")) {
View loadingIndicator = findViewById(R.id.loading_spinner);
loadingIndicator.setVisibility(View.VISIBLE);
emptyView = (TextView) findViewById(R.id.emptyList);
getLoaderManager().restartLoader(BOOKS_LOADER_ID, null, MainActivity.this);
recyclerView.addOnItemTouchListener(
new RecyclerItemClickListener(MainActivity.this, recyclerView, new RecyclerItemClickListener.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
if (isOnline()) {
Log.i(LOG_TAG, "TEST: detail activity clicked ...");
Books book = books_list.get(position);
Intent i = new Intent(MainActivity.this, DetailActivity.class);
i.putExtra("imageLink", book.getImageUrl());
i.putExtra("title", book.getTitle());
i.putExtra("authors", book.getWriter());
i.putExtra("description", book.getDescription());
i.putExtra("infoLink", book.getInfoLink());
startActivity(i);
}
else {
Toast.makeText(MainActivity.this,"No Internet Connection",Toast.LENGTH_SHORT).show();
}
}
@Override
public void onLongItemClick(View view, int position) {
// do whatever
}
})
);
}
}
});
getLoaderManager();
Log.i(LOG_TAG, "TEST: onCreate() finish ...");
}
//Update the adapter with books data
private void updateUi(List<Books> books) {
adapter = new MyAdapter(books);
recyclerView.setAdapter(adapter);
}
@Override
public Loader<List<Books>> onCreateLoader(int i, Bundle bundle) {
Log.i(LOG_TAG, "TEST: onCreateLoader called ...");
return new BookLoader(MainActivity.this, book_searched);
}
@Override
public void onLoadFinished(Loader<List<Books>> loader, List<Books> books) {
books_list = books;
Log.i(LOG_TAG, "TEST: onLoaderFinished called ...");
// Hide loading indicator because the data has been loaded
View loadingIndicator = findViewById(R.id.loading_spinner);
loadingIndicator.setVisibility(View.GONE);
if (books == null) {
emptyView.setText("No Books Found");
emptyView.setVisibility(View.VISIBLE);
}
if (isOnline()) {
//code if online
if (books != null) {
emptyView.setVisibility(View.GONE);
updateUi(books);
}
} else {
books = new ArrayList<>();
updateUi(books);
emptyView.setText("No Internet Connection");
emptyView.setVisibility(View.VISIBLE);
}
}
@Override
public void onLoaderReset(Loader<List<Books>> loader) {
Log.i(LOG_TAG, "TEST: onLoaderReset called ...");
new MyAdapter(new ArrayList<Books>());
}
//helper method to check is device connected to internet or not
public boolean isOnline() {
ConnectivityManager conMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = conMgr.getActiveNetworkInfo();
if (netInfo == null || !netInfo.isConnected() || !netInfo.isAvailable()) {
return false;
}
return true;
}
public String getSearchTerm() {
EditText search_term = (EditText) findViewById(R.id.text_search_term);
book_searched = search_term.getText().toString();
book_searched = book_searched.replace(' ', '+');
return book_searched;
}
}
`
DetailActivity.java
package com.example.setha.booklisting;
import android.content.Intent;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
public class DetailActivity extends AppCompatActivity {
private String imageLink;
private String title;
private ArrayList<String> authors;
private String details;
private String infoLink;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
Bundle b = getIntent().getExtras();
imageLink = b.getString("imageLink");
title = b.getString("title");
authors = b.getStringArrayList("authors");
details = b.getString("description");
infoLink = b.getString("infoLink");
//code to show image of the book
ImageView imageView = (ImageView) findViewById(R.id.img_thumbnail);
Picasso.with(getBaseContext()).load(imageLink).into(imageView);
TextView title_textView = (TextView) findViewById(R.id.text_title);
title_textView.setText(title);
//code to show authors of the book
StringBuilder list_authors = new StringBuilder();
for(String author : authors){
list_authors.append(author + ", ");
}
TextView authors_textView = (TextView) findViewById(R.id.text_authors);
authors_textView.setText(list_authors.toString().substring(0,list_authors.length()-2));
TextView details_textView = (TextView) findViewById(R.id.text_description);
details_textView.setText(details);
Button moreInfo = (Button) findViewById(R.id.more_info_button);
moreInfo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Uri webpage = Uri.parse(infoLink);
Intent intent = new Intent(Intent.ACTION_VIEW, webpage);
startActivity(intent);
}
});
}
}
BookLoader
package com.example.setha.booklisting;
import android.content.AsyncTaskLoader;
import android.content.Context;
import android.util.Log;
import java.util.List;
/**
* Created by setha on 14-08-2017.
*/
public class BookLoader extends AsyncTaskLoader<List<Books>> {
private String LOG_TAG = BookLoader.class.getSimpleName();
private static final String GOOGLE_BOOKS_API_REQUEST_URL =
"https://www.googleapis.com/books/v1/volumes?q=&maxResults=40&key=AIzaSyAsPSjnbNPMNf_eQ03by1iOalftZsbpu14";
private String search_term;
public BookLoader(Context context, String search_term) {
super(context);
this.search_term = search_term;
}
@Override
protected void onStartLoading() {
forceLoad();
}
@Override
public List<Books> loadInBackground() {
Log.i(LOG_TAG,"TEST: loadInBackground() called ...");
String str = GOOGLE_BOOKS_API_REQUEST_URL;
int index_to_add_search_term = str.indexOf("?q=");
String url = str.substring(0,index_to_add_search_term + 3) + search_term + str.substring(index_to_add_search_term + 3);
String[] urls = {url};
Log.i(LOG_TAG,"TEST: url " + url);
// Don't perform the request if there are no URLs, or the first URL is null.
if (urls.length < 1 || urls[0] == null) {
return null;
}
return Utils.fetchBooksData(urls[0]);
}
}
答案 0 :(得分:0)
执行重新创建的方向活动时,在这种情况下,您必须将整个数据保存在Bundle对象中。
有关方向的更多细节, View.OnLayoutChangeListener
答案 1 :(得分:0)
使用一堆日志消息我发现第二个Activity中的设备旋转后跟第一个Activity中的后退按钮设置加载器为null。所以当load设置为null时,我必须初始化一个加载器,这个调用loadInBackground方法来加载数据。 这是一个解决了我的问题的代码片段。
//this handle the case of recyclerview getting empty on rotation. This will reload the RecyclerView with previously fetched loader data without calling loadInBackground method
if (getLoaderManager().getLoader(BOOKS_LOADER_ID) != null) {
Log.i(LOG_TAG, "TEST: loader showing previously fetched data ...");
getLoaderManager().initLoader(BOOKS_LOADER_ID, null, MainActivity.this);
OnSingleBookTouchListener();
}
//this handle the case of loader being set to null if I rotate the device in DetailActivity (e.g if in MainActivity device is in Portrait mode and by clicking on any RecyclerView item I start DetailActivity. If I rotate the device in Detail activity to landscape mode and press back button to get back to MainActivity RecyclerView gets empty). So this will restart a loader.
else {
Log.i(LOG_TAG, "TEST: LoaderManager reloaded ...");
if (!book_searched.equals("")) {
getLoaderManager().initLoader(BOOKS_LOADER_ID, null, MainActivity.this);
OnSingleBookTouchListener();
}
}
Log.i(LOG_TAG, "TEST: onCreate() finish ...");
}