Android 当屏幕方向更改时,RecyclerView将消失

Android 当屏幕方向更改时,RecyclerView将消失,android,android-recyclerview,android-orientation,Android,Android Recyclerview,Android Orientation,我正在开发一个应用程序,它每10秒点击一个web服务来获取数据,然后在一个RecyclerView中填充数据,如果返回的JSONarray中存在任何数据。一旦应用程序检索到数据,检索到的数据将从服务器中删除。因此,下次应用程序访问web服务时,可能会得到空阵列,直到新数据进入服务器 问题: 当手机旋转或屏幕方向改变时,RecyclerView将消失。这可能是因为android通常会破坏应用程序的现有活动,并在方向改变时重新创建它们。但在我的例子中,已经检索到的数据不会出现在服务器中,因此可以在重

我正在开发一个应用程序,它每10秒点击一个web服务来获取数据,然后在一个RecyclerView中填充数据,如果返回的JSONarray中存在任何数据。一旦应用程序检索到数据,检索到的数据将从服务器中删除。因此,下次应用程序访问web服务时,可能会得到空阵列,直到新数据进入服务器

问题: 当手机旋转或屏幕方向改变时,RecyclerView将消失。这可能是因为android通常会破坏应用程序的现有活动,并在方向改变时重新创建它们。但在我的例子中,已经检索到的数据不会出现在服务器中,因此可以在重新创建活动后显示

我认为它必须通过实现onSaveInstanceState方法来保存状态,但不确定如何在代码中实现它。谁能告诉我要做什么改变吗

MainActivity.java

public class MainActivity extends AppCompatActivity  implements SwipeRefreshLayout.OnRefreshListener{

List<DataModel> DataAdapterClassList;
RecyclerView recyclerView;
LinearLayoutManager recyclerViewlayoutManager;
RecyclerView.Adapter recyclerViewadapter;
ArrayList<String> SubjectNames;
RequestQueue requestQueue ;
SwipeRefreshLayout mSwipeRefreshLayout;
public MainActivity mainActivity;
View ChildView ;
int RecyclerViewClickedItemPOS ;
private static final String TAG = MainActivity.class.getSimpleName();
        .....//More declarations
@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    mainActivity = this;
    mRequestingLocationUpdates = false;
    mLastUpdateTime = "";
    // Update values using data stored in the Bundle.
    updateValuesFromBundle(savedInstanceState);
    mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
    mSettingsClient = LocationServices.getSettingsClient(this);
    setContentView(R.layout.activity_main);
    DataAdapterClassList = new ArrayList<>();
    SubjectNames = new ArrayList<>();
    recyclerView = (RecyclerView) findViewById(R.id.recyclerView1);
    recyclerView.setHasFixedSize(true);
    recyclerViewlayoutManager = new LinearLayoutManager(this);
    recyclerView.setLayoutManager(recyclerViewlayoutManager);
    recyclerViewlayoutManager.setReverseLayout(true);
    recyclerViewlayoutManager.setStackFromEnd(true);
            ......//location callbacks....
    startTimer();
    JSON_WEB_CALL();

}


/**Location Updates fields based on data stored in the bundle.*/
private void updateValuesFromBundle(Bundle savedInstanceState) {
    if (savedInstanceState != null) {
        if (savedInstanceState.keySet().contains(KEY_REQUESTING_LOCATION_UPDATES)) {
            mRequestingLocationUpdates = savedInstanceState.getBoolean(
                    KEY_REQUESTING_LOCATION_UPDATES);
        }
        if (savedInstanceState.keySet().contains(KEY_LOCATION)) {
            mCurrentLocation = savedInstanceState.getParcelable(KEY_LOCATION);
        }

        // Update the value of mLastUpdateTime from the Bundle and update the UI.
        if (savedInstanceState.keySet().contains(KEY_LAST_UPDATED_TIME_STRING)) {
            mLastUpdateTime = savedInstanceState.getString(KEY_LAST_UPDATED_TIME_STRING);
        }
        updateUI();
    }
}
    @Override
public void onResume() {
    super.onResume();
}

    .............//More Location Codes

@Override
public void onRefresh() {
    mSwipeRefreshLayout.setRefreshing(false);
    JSON_WEB_CALL();
}

public void JSON_WEB_CALL(){

    String HTTP_SERVER_URL= String.format("http://pastebin.com/mySampleApi/student/%1$s",mStudentRoll);
    JsonArrayRequest jsArrRequest = new JsonArrayRequest
            (Request.Method.POST, HTTP_SERVER_URL, null, new Response.Listener<JSONArray>() {

                @Override
                public void onResponse(JSONArray response) {
                    //mTxtDisplay.setText("Response: " + response.toString());

                    JSON_PARSE_DATA_AFTER_WEBCALL(response);
                    Log.i(TAG, "Hello");
                }
            }, new Response.ErrorListener() {

                @Override
                public void onErrorResponse(VolleyError error) {
                    // TODO Auto-generated method stub
                }
            }){

    };
    requestQueue = Volley.newRequestQueue(this);
    requestQueue.add(jsArrRequest);
}



public void JSON_PARSE_DATA_AFTER_WEBCALL(JSONArray array){

    for(int i = 0; i<array.length(); i++) {
        DataModel GetDataModel = new DataModel();
        JSONObject json = null;
        try {
            json = array.getJSONObject(i);
            GetDataModel.setId(json.getString("CLASS"));
            GetDataModel.setPlateNo(json.getString("HOUSE"));
            GetDataModel.setPlateCode(json.getString("IMAGEURL"));

        } catch (JSONException e) {
            e.printStackTrace();
        }
            DataAdapterClassList.add(GetDataModel);
            mSwipeRefreshLayout.setRefreshing(false);
        }
    if (array.length() != 0) {
    recyclerViewadapter = new NewRecyclerViewAdapter(DataAdapterClassList, this);
    recyclerView.setAdapter(recyclerViewadapter);
    SHOW_ALERT(array);
    sendNotification(recyclerView, array);
    }
}

@Override
public void onPause() {
    super.onPause();  
    }

@Override
public void onBackPressed() {
    moveTaskToBack(true);
}

}
public class NewRecyclerViewAdapter extends RecyclerView.Adapter<NewRecyclerViewAdapter.ViewHolder> {

Context context;
List<DataModel> dataModels;
private static int currentPosition = 0;
public Animation animationUp;
public  Animation animationDown;
public int mExpandedPosition=-1;

public NewRecyclerViewAdapter(List<DataModel> getDataAdapter, Context context){
    super();
    this.dataModels = getDataAdapter;
    this.context = context;
}


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

@Override
public void onBindViewHolder(final ViewHolder viewHolder, final int position) {
    DataModel dataAdapter =  dataModels.get(position)

    viewHolder.SudentClass.setText(dataAdapter.getSudentClass());
    viewHolder.SudentHouse.setText(dataAdapter.getSudentHouse());
    Glide.with(context).load(dataAdapter.getImgUrl()).into(viewHolder.imageView);
    viewHolder.linearLayout.setVisibility(View.GONE);
    final boolean isExpanded = position==mExpandedPosition;
    viewHolder.linearLayout.setVisibility(isExpanded?View.VISIBLE:View.GONE);
    viewHolder.itemView.setActivated(isExpanded);
    viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mExpandedPosition = isExpanded ? -1:position;
            //TransitionManager.beginDelayedTransition();
            notifyDataSetChanged();
        }
    });

}

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

dataAdapter.getSudentClass() ViewHolder extends RecyclerView.ViewHolder{

    public TextView StudentdataAdapter.getSudentClass();
    public TextView SudentHouse;
    public TextView StudentClass;
    public ImageView imageView;
    LinearLayout linearLayout;
    public ViewHolder(View itemView) {
        super(itemView);
        SudentHouse = (TextView) itemView.findViewById(R.id.vehicle_SudentHouse) ;
        StudentClass = (TextView) itemView.findViewById(R.id.vehicle_student_class) ;
        imageView = (ImageView) itemView.findViewById(R.id.imageView);
    }
}
}
public类MainActivity扩展AppCompatActivity实现SwipeRefreshLayout.OnRefreshListener{
列表数据适配器类列表;
回收视图回收视图;
直线布局经理回收服务布局经理;
适配器RecycleWebAdapter;
ArrayList主题名;
请求队列请求队列;
SwipeRefreshLayout mSwipeRefreshLayout;
公共活动;
查看儿童视图;
int RecycleServiceClickeditempos;
私有静态最终字符串标记=MainActivity.class.getSimpleName();
……更多声明
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
主要活动=此;
mRequestingLocationUpdates=false;
mLastUpdateTime=“”;
//使用包中存储的数据更新值。
updateValuesFromBundle(savedInstanceState);
mFusedLocationClient=LocationServices.getFusedLocationProviderClient(此);
mSettingsClient=LocationServices.getSettingsClient(此);
setContentView(R.layout.activity_main);
DataAdapterClassList=new ArrayList();
SubjectNames=新的ArrayList();
recyclerView=(recyclerView)findViewById(R.id.RecyclerViewW1);
recyclerView.setHasFixedSize(true);
recyclerViewlayoutManager=新的LinearLayoutManager(此);
recyclerView.setLayoutManager(recyclerViewlayoutManager);
recyclerViewlayoutManager.setReverseLayout(true);
RecycleServiceWLayoutManager.setStackFromEnd(true);
……位置回调。。。。
startTimer();
JSON_WEB_CALL();
}
/**位置根据捆绑包中存储的数据更新字段*/
私有void updateValuesFromBundle(Bundle savedInstanceState){
如果(savedInstanceState!=null){
if(savedInstanceState.keySet()包含(请求位置更新的键)){
mRequestingLocationUpdates=savedInstanceState.getBoolean(
按键(请求位置更新);
}
如果(savedInstanceState.keySet()包含(键位置)){
mCurrentLocation=savedInstanceState.getParcelable(键位置);
}
//从Bundle中更新mLastUpdateTime的值并更新UI。
如果(savedInstanceState.keySet()包含(键\u上次\u更新的\u时间\u字符串)){
mLastUpdateTime=savedInstanceState.getString(键\u上次\u更新\u时间\u字符串);
}
updateUI();
}
}
@凌驾
恢复时公开作废(){
super.onResume();
}
更多位置代码
@凌驾
公共void onRefresh(){
mSwipeRefreshLayout.setRefresh(false);
JSON_WEB_CALL();
}
public void JSON_WEB_CALL(){
String HTTP_SERVER_URL=String.format(“http://pastebin.com/mySampleApi/student/%1$s“,mStudentRoll);
JsonArrayRequest JSARRRESQUEST=新的JsonArrayRequest
(Request.Method.POST,HTTP_SERVER_URL,null,new Response.Listener()){
@凌驾
公共void onResponse(JSONArray响应){
//mTxtDisplay.setText(“响应:+Response.toString());
JSON在WEBCALL之后解析数据(响应);
Log.i(标记“Hello”);
}
},new Response.ErrorListener(){
@凌驾
公共无效onErrorResponse(截击错误){
//TODO自动生成的方法存根
}
}){
};
requestQueue=Volley.newRequestQueue(this);
add(jsArrRequest);
}
public void JSON\u解析\u数据\u WEBCALL之后(JSONArray数组){

对于(int i=0;i,您必须以有效的方式处理配置更改

在项目中尝试此代码

   @Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    super.onSaveInstanceState(savedInstanceState);
    mListState=recyclerView.getLayoutManager().onSaveInstanceState();
    mBundleRecyclerViewState.putParcelable(KEY_RECYCLER_STATE, mListState);
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    if (mBundleRecyclerViewState != null) {
        new Handler().postDelayed(new Runnable() {

            @Override
            public void run() {
                mListState = mBundleRecyclerViewState.getParcelable(KEY_RECYCLER_STATE);
                recyclerView.getLayoutManager().onRestoreInstanceState(mListState);

            }
        }, 50);

    }

    recyclerView.setLayoutManager(gridLayoutManager);
 }
这里我使用了
GridLayoutManager
,出于您的目的,您可以使用
LinearLayout

这里是完整工作项目的github链接


请浏览下面的链接-

想法很简单,如果我们设置

 // retain this fragment
 setRetainInstance(true);

在片段内部,则此片段不会在配置更改时被销毁。在此片段中调用API,并使用getter和setter获取数据,这样您就不会丢失数据。

当您旋转屏幕时,需要在mainActivity中的以下代码中使用将被保存的状态

    @Override
protected void onCreate(Bundle savedInstanceState) {
    if(savedInstanceState != null) {
        DataAdapterClassList = savedInstanceState.getIntegerArrayList("key");
    }

    // Pass the imagesState to the adapter as a parameter here
}

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putIntegerArrayList("key", DataAdapterClassList);
}

与共享您的
layout.xml
question@Nilesh添加了activity_main.xmlcheck my below ans@newcodersion因为我使用的是LinearLayoutManager,在if-else语句中应该写什么而不是setPanCount?因为您使用的是LinearLayoutManager,所以可以跳过该代码部分、整个if-else条件部分,并将布局设置为recyclerview这就是recyclerView.setLayoutManager(linearLayoutManager);我已经做了您提到的事情,但它仍然给了我相同的错误。他没有使用Fragment,他只是使用活动RecyclerView@akshay,正确。为了解决这个问题,我们必须使用Fragment。@NewCoder,我解释了“在activ中这行吗?”
    @Override
protected void onCreate(Bundle savedInstanceState) {
    if(savedInstanceState != null) {
        DataAdapterClassList = savedInstanceState.getIntegerArrayList("key");
    }

    // Pass the imagesState to the adapter as a parameter here
}

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putIntegerArrayList("key", DataAdapterClassList);
}