gpt4 book ai didi

java - 无法在屏幕旋转时保持 RecyclerView 位置

转载 作者:太空狗 更新时间:2023-10-29 15:50:02 26 4
gpt4 key购买 nike

我正在加载一个 RecyclerView,它基于对 Retrofit 的调用和存储在本地 SQLite 数据库中的数据。

在屏幕旋转时,RecyclerView 不断重置。此外,当我 Collection 一部电影(将电影添加到我的本地房间数据库)时,有时我的微调器与要填充到 RecyclerView 中的数据不对齐。下面是我的代码:

public class MainActivity extends AppCompatActivity {

private RecyclerView mMovieResults;
private MyAdapter mMovieResultsAdapter;
private String query;
private String mBaseURL;
private int lastFirstVisiblePosition;
//TODO: How is someone able to load my API Key if I am storing it


private ArrayList<String> mMovieURLS;
private ArrayList<Movie> mMovies;
private List<Movie> mMovieResultsList;

private static final String SPINNER_SELECTION = "SPINNER_SELECTION";

private boolean mIsFavoriteSelected;

private AppDatabase mDb;

private Spinner mSpinner;

private SharedPreferences mPrefs;
private SharedPreferences.Editor mPrefsEditor;

private static Bundle mBundleRecyclerViewState;


private int saved_selection = -1;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v("ONCREATE", "ONCREATE");
if (savedInstanceState != null){
saved_selection = savedInstanceState.getInt(SPINNER_SELECTION);
}

if (isOnline()) {
setContentView(R.layout.activity_main);
Stetho.initializeWithDefaults(this);
mDb = AppDatabase.getInstance(getApplicationContext());
mMovieResults = findViewById(R.id.main_recyclerview_image_results);
GridLayoutManager glm = new GridLayoutManager(this, 3);
glm.setOrientation(LinearLayoutManager.VERTICAL);
mMovieResults.setLayoutManager(glm);
mMovieURLS = new ArrayList<>();
mMovies = new ArrayList<>();
mMovieResultsList = new ArrayList<>();
mMovieResultsAdapter = new MyAdapter(mMovieResultsList);
mMovieResults.setAdapter(mMovieResultsAdapter);
mDb = AppDatabase.getInstance(getApplicationContext());
mPrefs = getSharedPreferences("prefs", MODE_PRIVATE);

mPrefsEditor = mPrefs.edit();
switch (saved_selection){
case 0:
mBaseURL = "https://api.themoviedb.org/3/movie/popular/";
calltoRetrofit(mBaseURL);
break;
case 1:
mBaseURL = "https://api.themoviedb.org/3/movie/top_rated/";
calltoRetrofit(mBaseURL);
break;
case 2:
mIsFavoriteSelected = true;
mMovieURLS.clear();
retrieveMovies();
break;

default:
mBaseURL = "https://api.themoviedb.org/3/movie/popular/";
break;
}


} else {
setContentView(R.layout.activity_no_internet);
return;
}

}





@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.action_bar_spinner, menu);
MenuItem item = menu.findItem(R.id.spinner);
mSpinner = (Spinner) item.getActionView();
if (isOnline()) {
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(getApplicationContext(), R.array.spiner_list_item_array, R.layout.custom_spinner);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mSpinner.setAdapter(adapter);
if (saved_selection >= 0){
mSpinner.setSelection(saved_selection);
}
mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
mPrefsEditor.putInt(SPINNER_SELECTION, i);
mPrefsEditor.commit();
switch (i) {
case 0:
mBaseURL = "https://api.themoviedb.org/3/movie/popular/";
calltoRetrofit(mBaseURL);
break;
case 1:
mBaseURL = "https://api.themoviedb.org/3/movie/top_rated/";
calltoRetrofit(mBaseURL);
break;
case 2:
mIsFavoriteSelected = true;
mMovieURLS.clear();
retrieveMovies();
break;

default:
mBaseURL = "https://api.themoviedb.org/3/movie/popular/";
break;
}


}

@Override
public void onNothingSelected(AdapterView<?> adapterView) {

}
});
return true;
} else {
return true;
}
}

@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putInt(SPINNER_SELECTION, mSpinner.getSelectedItemPosition());
super.onSaveInstanceState(outState);
}



@Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
int x = item.getItemId();
Log.v("OPTIONS_ID", String.valueOf(x));
return true;
}

private void retrieveMovies() {
//TODO: I am unsure if I am handling correctly. When I favorite and unfavorite a movie, and then go back to the MainActivity, it is not displaying the correct item from the Spinner.
//TODO: For example, favorites may be listed in the Spinner, however the screen may be displaying "TOP"
//TODO: How could I tell if I am making unnecessary queries to Room? I know it is a project requirement, but I was not sure how to handle if I am making unnecessary calls
//TODO: on screen rotation
MainViewModel viewModel = ViewModelProviders.of(this).get(MainViewModel.class);
final LiveData<List<Movie>> movies = viewModel.getMovies();
movies.observe(this, new Observer<List<Movie>>() {
@Override
public void onChanged(@Nullable final List<Movie> movies) {
for (Movie movie : movies) {
String photoURL = "http://image.tmdb.org/t/p/w185" + movie.getPoster_path();
Log.v("FAVORITE_URL", photoURL);
mMovieURLS.add(photoURL);
}
runOnUiThread(new Runnable() {
@Override
public void run() {
mMovieResultsList = movies;
mMovieResultsAdapter.notifyDataSetChanged();
}
});

}
});
}





@Override
protected void onResume() {
super.onResume();
((GridLayoutManager) mMovieResults.getLayoutManager()).scrollToPositionWithOffset(lastFirstVisiblePosition,0);
}

private void calltoRetrofit(String mBaseURL) {
mMovieURLS.clear();
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
OkHttpClient client = new OkHttpClient
.Builder()
.addInterceptor(interceptor)
.build();

Retrofit retrofit = new Retrofit.Builder()
.baseUrl(mBaseURL)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();

final ApiInterface apiInterface = retrofit.create(ApiInterface.class);

Log.v("API", API_KEY);
Call<Movies> call = apiInterface.getImages(API_KEY);
call.enqueue(new Callback<Movies>() {
@Override
public void onResponse(Call<Movies> call, Response<Movies> response) {
Log.v("RESPONSE", response.body().toString());
String totalPages = String.valueOf(response.body().getTotal_pages());
Log.v("TOTAL", totalPages);
mMovieResultsList = response.body().getResults();
for (Movie movie : mMovieResultsList) {
if (movie.getPoster_path() != null) {
String photoURL = "http://image.tmdb.org/t/p/w185" + movie.getPoster_path();
mMovieURLS.add(photoURL);
}
mMovieResultsAdapter.notifyDataSetChanged();
}
}

@Override
public void onFailure(Call<Movies> call, Throwable t) {
Log.v("FAILURE", t.toString());
}
});
}



@Override
public void onPointerCaptureChanged(boolean hasCapture) {

}

@Override
protected void onPause() {
super.onPause();
lastFirstVisiblePosition = ((GridLayoutManager)mMovieResults.getLayoutManager()).findFirstCompletelyVisibleItemPosition();

}

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {


public class ViewHolder extends RecyclerView.ViewHolder {

protected ImageView mResultImage;

public ViewHolder(View itemView) {
super(itemView);
mResultImage = itemView.findViewById(R.id.movie_poster_image);
}
}


public MyAdapter(List<Movie> mDataset) {
mMovieResultsList = mDataset;
}

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.movie_poster_image, parent, false);
return new ViewHolder(v);
}

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
final String urlForPhoto = "http://image.tmdb.org/t/p/w185" + mMovieResultsList.get(position).getPoster_path();

Picasso.get()
.load(urlForPhoto)
.into(holder.mResultImage);

holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent i = new Intent(getApplicationContext(), IndividualMovieActivity.class);
i.putExtra("Movie", mMovieResultsList.get(position));
startActivity(i);
}
});

}

@Override
public int getItemCount() {
return mMovieResultsList.size();
}

}

public interface ApiInterface {
@GET("?language=en-US")
Call<Movies> getImages(@Query("api_key") String api_key);
}

private boolean isOnline() {
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
return netInfo != null && netInfo.isConnectedOrConnecting();
}

最佳答案

RecyclerView 只会保存它向上滚动的位置,直到您调用 setAdapter。通过在您仍然没有数据时调用 setAdapter,滚动位置将被丢弃(如果没有位置 4,则无法滚动到位置 4)。

你应该等到你有数据调用setAdapter

关于java - 无法在屏幕旋转时保持 RecyclerView 位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51393115/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com