2017-08-15 75 views
0

问题的标题可能有点混乱,但作为初学者,我发现编写精确标题非常困难。现在,我正在制作一个应用程序,可以从Google书籍API获取数据,并在RecyclerView中显示它们。点击搜索按钮后,数据将加载到RecyclerView中。当我点击适配器的Individual Item时,它会打开DetailActivity。该应用程序正常工作如果我在MainActivity中旋转设备,但是如果我在DetailActivity中旋转设备,然后按下返回按钮,则MainActivity适配器为空。 MainActivity.java当设备旋转时,Android获得空的第一个活动是第一个活动中使用LoaderManager旁边的第二个活动和后退按钮

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

当您执行定向活动重建,在这种情况下,你必须保存你的整个Bundle对象中的数据。

约取向更详细地, click here

+0

我不认为你可以保存加载器实例,在活动重新创建后使用。 –

0

使用一堆日志消息的我想通了,在第二个活动,随后在第一活动返回按钮组装载装置旋转为空。所以当loader将loader设置为null时,我必须初始化一个loader,这个调用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 ..."); 
} 
相关问题