Learn, Share, Build

233
October 10, 2017, at 12:21 PM

When I rotate my device, my activity instance is destroyed which starts a new onCreate. I can't figure out how to repopulate my RecyclerView after screen orientation. I have tried some solutions involing AndroidManifest: android:configChanges="keyboardHidden|orientation" and also with onSaveInstanceState, but could not get it to work. I have addedonSaveInstanceStateandonRestoreInstanceState` base code to my question, which does not do anything at the moment.

Thanks

MainActivity.java

public class MainActivity extends AppCompatActivity implements RepositoryAdapter.OnItemClickListener {
    private static final String LOG_TAG = "MainActivity";
    @BindView(R.id.fab_search_github_user)
    FloatingActionButton fabSearchGitHubUser;
    @BindView(R.id.et_search_user)
    EditText etSearchUser;
    @BindView(R.id.btn_search_user)
    Button btnSearchUser;
    @BindView(R.id.github_user)
    TextView tvOwner;
    @BindView(R.id.github_repository_recyclerview)
    RecyclerView mRecyclerView;
    private RepositoryAdapter mAdapter;
    private Api mApi;
    private Owner mOwner;
    boolean isSearchToggled = false;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        ButterKnife.bind(this);
        mApi = ApiUtils.getApi();
        // RecyclerView
        RecyclerView.LayoutManager linearLayoutManager = new LinearLayoutManager(getApplicationContext());
        mRecyclerView.setLayoutManager(linearLayoutManager);
        mRecyclerView.setHasFixedSize(true);
        // Floating action button to toggle user search field.
        FloatingActionButton floatingActionButton = (FloatingActionButton) findViewById(R.id.fab_search_github_user);
        floatingActionButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                toggleSearch();
            }
        });
    }
    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        super.onSaveInstanceState(savedInstanceState);
    }
    @Override
    public void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
    }
    @OnClick(R.id.btn_search_user)
    public void onSearchBtnClicked(View view) {
        if (!TextUtils.isEmpty(etSearchUser.getText())) {
            String searchedUser = etSearchUser.getText().toString();
            // Search will be done offline when no internet, otherwise online.
            if (!isNetworkAvailable()) {
                Toast.makeText(this, "No internet, searching offline", Toast.LENGTH_SHORT).show();
                mOwner = Owner.getByUsername(searchedUser);
                if (mOwner != null) {
                    searchByUsername(searchedUser);
                    tvOwner.setText(searchedUser);
                } else {
                    if (mAdapter != null) {
                        mAdapter.clearRecyclerView();
                    }
                    tvOwner.setText(getString(R.string.user_not_found, searchedUser));
                }
            } else {
                loadRepository(searchedUser);
                tvOwner.setText(searchedUser);
                Toast.makeText(this, "Searching online", Toast.LENGTH_SHORT).show();
            }
        } else {
            Log.i(LOG_TAG, "Search field is empty");
        }
        if (view != null) {
            InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
        }
        toggleSearch();
    }
    /**
     * Search local user by username.
     *
     * @param username The local user that is searched for.
     */
    public void searchByUsername(String username) {
        mAdapter = new RepositoryAdapter(Repository.getList(username), MainActivity.this);
        mRecyclerView.setAdapter(mAdapter);
    }
    /**
     * Search online on GitHub to retrieve all user repositories.
     *
     * @param username The GitHub user that is searched for.
     */
    public void loadRepository(String username) {
        mApi.listRepository(username).enqueue(new Callback<List<Repository>>() {
            @Override
            public void onResponse(Call<List<Repository>> call, Response<List<Repository>> response) {
                mAdapter = new RepositoryAdapter(response.body(), MainActivity.this);
                mRecyclerView.setAdapter(mAdapter);
            }
            @Override
            public void onFailure(Call<List<Repository>> call, Throwable t) {
                Log.e("MainActivity", "error loading from API");
            }
        });
    }
    @Override
    public void onItemClick(Repository repository) {
        if (isNetworkAvailable()) {
            mOwner = Owner.getByUsername(repository.owner.getLogin());
            Repository mRepository = Repository.getByRepositoryName(repository.getName());
            if (mOwner != null) {
                if (mRepository != null) {
                    // Repository is already in Database.
                } else {
                    // Selected repository is added to Database
                    mRepository = new Repository(mOwner);
                    mRepository.setName(repository.getName());
                    mRepository.setLogin(repository.owner.getLogin());
                    mRepository.setDescription(repository.getDescription());
                    mRepository.setStargazersCount(repository.getStargazersCount());
                    mRepository.setForksCount(repository.getForksCount());
                    mRepository.save();
                }
            } else {
                // selected repository and its owner are added to Database
                mOwner = new Owner();
                mOwner.setLogin(repository.owner.getLogin());
                mOwner.setAvatarUrl(repository.owner.getAvatarUrl());
                mOwner.setReposUrl(repository.owner.getReposUrl());
                mOwner.save();
                mRepository = new Repository(mOwner);
                mRepository.setName(repository.getName());
                mRepository.setLogin(repository.owner.getLogin());
                mRepository.setDescription(repository.getDescription());
                mRepository.setStargazersCount(repository.getStargazersCount());
                mRepository.setForksCount(repository.getForksCount());
                mRepository.save();
            }
        }
        // Send intent with repository name to repository detail activity.
        Intent intent = new Intent(MainActivity.this, RepositoryDetailActivity.class);
        intent.putExtra(INTENT_KEY_REPOSITORY, repository.getName());
        startActivity(intent);
    }
    /**
     * Toggle search field according to its state.
     */
    private void toggleSearch() {
        if (!isSearchToggled) {
            etSearchUser.setVisibility(View.VISIBLE);
            btnSearchUser.setVisibility(View.VISIBLE);
            isSearchToggled = true;
        } else {
            etSearchUser.setVisibility(View.GONE);
            btnSearchUser.setVisibility(View.GONE);
            isSearchToggled = false;
        }
    }
    /**
     * Checks if network is available on the device.
     *
     * @return Return when networkInfo is not null and networkInfo is connected.
     */
    private boolean isNetworkAvailable() {
        ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
        return networkInfo != null && networkInfo.isConnected();
    }
}
Answer 1
  1. configChanges also should include screenSize if you want turn off recreating activity class. So correct version:

    android:configChanges="keyboardHidden|orientation|screenSize"

  2. In order to save recycler view content without disabling recreating you have to store content in some place which is not bound to activity lifecycle or pass it to bundle in onSaveInstanceState and get it later in onRestoreInstanceState or in onCreate. Please, take a look at https://developer.android.com/guide/components/activities/activity-lifecycle.html

Rent Charter Buses Company
READ ALSO
Learn, Share, Build

Learn, Share, Build

There is processing to acquire the image held by android using the cursorThe cursor needs authorization to external storage

296
Learn, Share, Build

Learn, Share, Build

I am using Ionic together with the native Geolocation plugin to retrieve user position and sort a list of position by closest to the userThe Geolocation plugin works perfectly using ionic serve or ionic lab as well as iOS devices but it does not work on Android...

278
Learn, Share, Build

Learn, Share, Build

Now I`m using MPandroidchartand my chart is showing sensing data

242
Learn, Share, Build

Learn, Share, Build

I am developing react native application on Windows 7 64-bit, my target OS is Android 60 running on Moto G4 Plus device

288