【问题标题】:notifyDataSetChanged stop working after onDestroy in fragmentnotifyDataSetChanged 在片段中的 onDestroy 后停止工作
【发布时间】:2017-01-15 14:23:36
【问题描述】:

我有一个fragment,里面有一个RecyclerView。一切正常,但是当我按下主页,在其他应用程序中导航,然后返回我的应用程序时,视图被重新创建,我的ArrayList(从onSaveInstanceState 恢复)没有显示在我的recyclerview 中,这不起作用即使在更新列表之后。

这里有一些代码:

-活动

public class MainActivity extends AppCompatActivity {

    FragmentTransaction ft;
    BottomNavigationView bottomNavigationView;
    int current;
    private FirebaseAnalytics mFirebaseAnalytics;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        if(savedInstanceState==null) {
            setupFragment();
        }

//        mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);


        bottomNavigationView = (BottomNavigationView)
            findViewById(R.id.bottom_navigation);

    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

    bottomNavigationView.setOnNavigationItemSelectedListener(
            new BottomNavigationView.OnNavigationItemSelectedListener() {
                @Override
                public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                    int id = item.getItemId();
                    switch (id) {
                        case R.id.action_golden_hour:
                            changeFragment(new GoldenFragment(), "GOLDEN");
                            current=0;
                            break;
                        case R.id.action_hyperfocal:
                            changeFragment(new HyperFragment(), "HYPER");
                            current=1;
                            break;
                        case R.id.action_ir:
                            changeFragment(new IrFragment(), "IR");
                            current=2;
                            break;
                        case R.id.action_nd:
                            changeFragment(new NdFragment(), "ND");
                            current=3;
                            break;
                    }
                    return true;
                }
            });
}

@SuppressLint("CommitTransaction")
private void setupFragment(){
    ft = getSupportFragmentManager().beginTransaction();
    ft.add(R.id.main_fragment, new GoldenFragment()).commit();
    current=0;
}

@SuppressLint("CommitTransaction")
private void changeFragment(Fragment fragment, String tag){
    ft = getSupportFragmentManager().beginTransaction();
    ft.replace(R.id.main_fragment, fragment, tag).commit();
}

-片段

public class GoldenFragment extends Fragment implements DatePickerDialog.OnDateSetListener{

SupportPlaceAutocompleteFragment autocompleteFragment;
RecyclerView rv;
CustomAdapter adapter;
ProgressBar pb;
ArrayList<Hours> hours;
CardView cv;
TextView emptyGoldenText;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    thisContext = getContext();
    setHasOptionsMenu(true);
    ampm = !android.text.format.DateFormat.is24HourFormat(thisContext);

    hours = new ArrayList<>();
    adapter = new CustomAdapter(thisContext, hours);

    if(savedInstanceState!=null) {
        Log.d(TAG,"inState not null");
        hours.clear();
        hours = savedInstanceState.getParcelableArrayList("HoursList");
    }

    Log.d(TAG,"onCreate() called");
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    if(view == null) {
        view = inflater.inflate(R.layout.fragment_golden, container, false);
    }
    Toolbar goldenToolbar = (Toolbar) view.findViewById(R.id.toolbar_golden);
    ((AppCompatActivity) getActivity()).setSupportActionBar(goldenToolbar);

    emptyGoldenText = (TextView) view.findViewById(R.id.empty_golden_text);

    autocompleteFragment = (SupportPlaceAutocompleteFragment) getChildFragmentManager()
            .findFragmentById(R.id.place_autocomplete_fragment);

    if (autocompleteFragment == null) {
        autocompleteFragment  = (SupportPlaceAutocompleteFragment) SupportPlaceAutocompleteFragment
                .instantiate(thisContext, "com.google.android.gms.location.places.ui.SupportPlaceAutocompleteFragment");
    }
    autocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
        @Override
        public void onPlaceSelected(Place place) {
            Log.i(TAG, "Place: " + place.getName());
            try {
                new GeoCoding()
                        .execute("https://maps.googleapis.com/maps/api/geocode/json?address="+place.getName()+"&key="+geoKEY);
            } catch (Exception e) {
                Toast.makeText(thisContext,"Cannot contact Google's servers, please try later.", Toast.LENGTH_SHORT).show();
                e.printStackTrace();
            }
        }

        @Override
        public void onError(Status status) {
            Log.i(TAG, "An error occurred: " + status);
        }
    });
    getChildFragmentManager().beginTransaction()
            .replace(R.id.place_autocomplete_fragment, autocompleteFragment).commit();

    //Initialize RecyclerView
    rv = (RecyclerView)view.findViewById(R.id.list_golden);
    rv.setLayoutManager(new LinearLayoutManager(thisContext));
    DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(rv.getContext(),
            getActivity().getResources().getConfiguration().orientation);
    rv.addItemDecoration(dividerItemDecoration);
    rv.setAdapter(adapter);

    cv = (CardView) view.findViewById(R.id.cv_golden);
    pb = (ProgressBar) view.findViewById(R.id.progress_bar);

    if(savedInstanceState==null) {
        Log.d(TAG,"New empty data set");

        rv.setVisibility(View.GONE);
        cv.setVisibility(View.GONE);
        pb.setVisibility(View.INVISIBLE);
    }
    else{
        Log.d(TAG,"Old data set");

        adapter.notifyDataSetChanged();
        pb.setVisibility(View.INVISIBLE);
        rv.setVisibility(View.VISIBLE);
        cv.setVisibility(View.VISIBLE);
        emptyGoldenText.setVisibility(View.INVISIBLE);
    }

    Log.d(TAG,"onCreateView() called");
    return view;
}

@Override
public void onSaveInstanceState(Bundle outState){
    super.onSaveInstanceState(outState);
    outState.putParcelableArrayList("HoursList",hours);
    Log.d(TAG,"onSaveInstanceState called");
}

已解决 移动解决

adapter = new CustomAdapter(thisContext, hours);

onCreate() 到onCreateView()。

【问题讨论】:

    标签: android android-fragments android-recyclerview


    【解决方案1】:

    在activity中,你必须将fragment的实例保存在onSaveInstanceState()并恢复到onCreate()

    @Override
    public void onCreate(Bundle savedInstanceState) {
        ...
        if (savedInstanceState != null) {     
            fragment = getSupportFragmentManager().getFragment(savedInstanceState, "KEY");
            changeFragment(fragment, "MY TAG")
        } else {
            setupFragment();
        }
        ...
    }
    
    
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
    
        Fragment fragment = getSupportFragmentManager().findFragmentByTag("MY TAG");
        if (fragment != null) {
            getSupportFragmentManager().putFragment(outState, "KEY", fragment);
        }
    }
    

    【讨论】:

    • 这不起作用,片段被恢复但 RecyclerView 仍然不起作用。我确定 ArrayList 不为空,但 adapter.notifydatasetchanged() 什么都不做。
    【解决方案2】:

    试试这个代码:在onSaveInstanceState放数组列表

         @Override
    public void onSaveInstanceState(Bundle outState){
        super.onSaveInstanceState(outState);
        outState.putParcelableArrayList("HoursList",hours);
        Log.d(TAG,"onSaveInstanceState called");
      }
    

    onActivityCreated 中检查以下条件:

     @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            if(savedInstanceState! = null) {
                    //probably orientation change
                    Log.d(TAG,"inState not null");
                    hours.clear();
                    hours = savedInstanceState.getParcelableArrayList("HoursList");
                    //check if u get the value print log
                }
            else {
                if (hours != null) {
                    //returning from backstack, data is fine, do nothing
                } else {
                    //newly created, compute data
                    hours = computeData();
                }
            }
        }
    

    【讨论】:

    • 试过了,但这不起作用。我认为我的代码做同样的事情,但在 onCreate。问题是当我调用 adapter.notifydatasetchanged 时:recyclerview 没有被填充。
    • 如果您的 getItemCount() 返回 0,则 notifyDataSetChanged() 不会执行任何操作。确保在初始化适配器时,您传递的是有效数据集。
    • 我注意到我的列表不是空的,但我的适配器是所以我移动了 adapter = new CustomAdapter(thisContext, hours);从 OnCreate() 到 OnCreateView() 并且成功了。
    猜你喜欢
    • 2019-07-16
    • 2022-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多