作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我目前在方向更改后恢复 ArrayList 的位置以增强用户体验时遇到错误。我尝试存储 ArrayList 并已将 movieData 可打包。当方向更改后使用调试器时,savedInstance 显然不为 null,并且包含一个 int 值,并且可能是可包裹数组列表,我真的不知道为什么这段代码还不起作用。
fragment 类:
public class MovieGridFragment extends Fragment {
public clickInterfaceHelper clickListener;
private GridView movieGridView;
private int index;
public List<movieData> movieDataList = new ArrayList<>();
public ArrayList<movieData> restoreList;
public MovieGridFragment() {} //empty constructor
@Override
public void onAttach(Context context) {
super.onAttach(context);
}
public void setClickListener(clickInterfaceHelper listener) {
this.clickListener = listener;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState != null)
index = savedInstanceState.getInt("INDEX");
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
setHasOptionsMenu(true);
if(movieDataList.isEmpty() && networkChecker.isNetworkAvailableChecker(getContext())) {
movieDataList = new ArrayList<movieData>();
}
if(!movieDataList.isEmpty() && !networkChecker.isNetworkAvailableChecker(getContext())) {
movieDataList = new ArrayList<movieData>();
}
View rootView = inflater.inflate(R.layout.movie_display_fragment, container, false);
movieGridView = (GridView) rootView.findViewById(R.id.gv_movie_display);
if(savedInstanceState != null && savedInstanceState.containsKey("OLDMOVIEDATA")) {
//index = savedInstanceState.getInt("INDEX");
//movieDataList.addAll(Arrays.asList((movieData[]) savedInstanceState.getSerializable("OLDMOVIEDATA")));
restoreList = savedInstanceState.getParcelableArrayList("OLDMOVIEDATA");
movieAdapter adapter = new movieAdapter(getActivity(),restoreList);
adapter.notifyDataSetChanged();
//movieGridView.setAdapter(adapter);
movieGridView.smoothScrollToPosition(index);
}
else {
movieAdapter adapter = new movieAdapter(getActivity(), movieDataList);
adapter.notifyDataSetChanged();
movieGridView.setAdapter(adapter);
}
movieGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if(clickListener != null)
clickListener.clickOnItem(position);
}
});
return rootView;
}
@Override
public void onSaveInstanceState(Bundle outState) {
//outState.putSerializable("OLDMOVIEDATA",movieData.movieDataArray);
outState.putParcelableArrayList("OLDMOVIEDATA",restoreList);
outState.putInt("INDEX",movieGridView.getFirstVisiblePosition());
super.onSaveInstanceState(outState);
}
}
适配器:
public class movieAdapter extends ArrayAdapter<movieData> {
public movieAdapter(Context context, List<movieData> movieObject) {
super(context, 0, movieObject);
}
public View getView(int pos, View convertingView, ViewGroup viewGroup) {
movieData movieDatas = getItem(pos);
String url="http://image.tmdb.org/t/p/w185"+movieDatas.getMovieImagePath();
if(convertingView == null)
convertingView = LayoutInflater.from(getContext()).inflate(R.layout.image_display,viewGroup,false);
ImageView imageView = (ImageView) convertingView.findViewById(R.id.iv_movie_image);
Picasso.with(getContext()).load(url.trim()).into(imageView);
return convertingView;
}
}
以及主要 Activity :
public class MainActivity extends AppCompatActivity implements clickInterfaceHelper {
public static String sorterString = null;
public static String urlBase = "https://api.themoviedb.org/3/movie/";
public static String urlFinal = null;
RequestQueue requestQueue;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(savedInstanceState == null) {
MovieGridFragment fragment = new MovieGridFragment();
fragment.setClickListener(this);
getSupportFragmentManager().beginTransaction()
.add(R.id.activity_container, fragment)
.commit();
movieData.movieDataPosition = 0;
}
if(savedInstanceState != null) {
sorterString = savedInstanceState.getString("SORTER");
}
if(sorterString==null)
sorterString="popular?";
if(sorterString!="favorite" && sorterString!=null) {
if(networkChecker.isNetworkAvailableChecker(this)) {
movieRequest();
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu_act, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if(id == R.id.m_popularity_action) {
if(sorterString != "popular?") {
sorterString = "popular?";
if(networkChecker.isNetworkAvailableChecker(this))
movieRequest();
}
return true;
}
if(id == R.id.m_action_voter) {
if(sorterString != "top_rated?") {
sorterString = "top_rated?";
if(networkChecker.isNetworkAvailableChecker(this))
movieRequest();
}
return true;
}
if(id == R.id.m_favorite_btn) {
if(sorterString != "favorite") {
SQLiteOpenHelper helper = new movieDataDbHelper(this);
SQLiteDatabase database = helper.getReadableDatabase();
Cursor cursor= database.query(movieDataContract.contractEntry.TABLE_NAME,
new String[] {
movieDataContract.contractEntry.ID,
movieDataContract.contractEntry.IMG_PATH},null,null,null,null,null);
if(cursor.getCount() == 0) {
Toast.makeText(this, "there are no favorite movies yet!",Toast.LENGTH_SHORT).show();
} else {
sorterString = "favorite";
showFavoriteFragment();
}
database.close();
helper.close();
cursor.close();
}
return true;
}
return super.onOptionsItemSelected(item);
}
public void showFavoriteFragment() {
favoriteMoviesDetailsFragment fragment = new favoriteMoviesDetailsFragment();
try {
getFragmentManager().beginTransaction().replace(R.id.activity_container,fragment).commit();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
outState.putString("SORTER", sorterString);
outState.putInt("POSITION",movieData.movieDataPosition);
super.onSaveInstanceState(outState, outPersistentState);
}
public void movieRequest() {
final MovieGridFragment gridFragment = new MovieGridFragment();
gridFragment.setClickListener(this);
urlFinal = urlBase + sorterString + movieData.apiKey;
urlFinal.trim();
requestQueue = Volley.newRequestQueue(this);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, urlFinal, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
JSONArray array = response.getJSONArray("results");
movieData.movieDataArray = new movieData[array.length()];
for (int i = 0; i < array.length(); i++) {
movieData movie = new movieData();
JSONObject jsonObject = array.getJSONObject(i);
movie.setMovieId(jsonObject.getString("id"));
movie.setMovieImagePath(jsonObject.getString("poster_path"));
movie.setMovieTitle(jsonObject.getString("original_title"));
movie.setMoviePlot(jsonObject.getString("overview"));
movie.setMovieVoting(jsonObject.getString("vote_average"));
movie.setMovieReleaseDate(jsonObject.getString("release_date"));
movieData.movieDataArray[i] = movie;
}
gridFragment.movieDataList = Arrays.asList(movieData.movieDataArray);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.activity_container, gridFragment);
try {
transaction.commitAllowingStateLoss();
} catch (Exception e) {
e.printStackTrace();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("volley", String.valueOf(error));
}
}
);
requestQueue.add(jsonObjectRequest);
}
@Override
public void clickOnItem(int id) {
movieData.movieDataPosition = id;
if(movieData.movieDataArray == null) {
movieRequest();
} else {
Intent intent = new Intent(this, detailsActivity.class);
intent.putExtra("FRAGMENT","MOVIE");
startActivity(intent);
}
}
@Override
public void favoriteMovieItem(int movieId) {
movieData.dbPosition = movieId;
Intent intent = new Intent(this,detailsActivity.class);
intent.putExtra("FRAGMENT","favorite");
startActivity(intent);
}
}
最佳答案
您已经使用
@Override
public void onSaveInstanceState(Bundle outState) {
//outState.putSerializable("OLDMOVIEDATA",movieData.movieDataArray);
outState.putParcelableArrayList("OLDMOVIEDATA",restoreList);
outState.putInt("INDEX",movieGridView.getFirstVisiblePosition());
super.onSaveInstanceState(outState);
}
只需用它来存储您需要保存的位置即可。使用“onCreateView”中给出的包获取位置。
如果不起作用,请将“setRetainInstance(true)”放入 fragment 的“onCreate”函数中。它将防止您的 fragment 在方向改变期间被破坏然后从无到有重新创建。但是,我在某处读到,对于具有 UI 元素的 fragment 来说这不是正确的方法(但我从未发现这样做有任何问题)。
如果您想要一种不使用“setRetainInstance”的替代方法,请存储(并恢复) Activity 上的位置
public void onSaveInstanceState(Bundle outState)"
功能。为此,请在 fragment 中创建一个函数“getPosition()”,在 Activity saveInstanceState 中调用它,并在 fragment 中创建一个函数“refresh(intposition)”(并在恢复的位置值上调用它)在 Activity 中加载/重新创建。
关于java - 如何在方向更改时保存 ArrayLists 位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42791116/
我是一名优秀的程序员,十分优秀!