Screen rotation adapter notifyDataSetChanged not working - java

I have a problem with updating RecyclerView when rotating the screen. By clicking on fab button I'm showing dialog fragment with input fields. Then when I'm rotating the screen and saving data my RecyclerView is not updating. I'm setting adapter in onCreate method. I should rotate once more in order to see fresh data. How can solve this issue.
Thanks in advance.
dataSource = new MyBusinessDataSource(this);
try
{
dataSource.openForRead();
}
catch (SQLException sqlEx)
{
Toast.makeText(MyBusinessMainActivity.this, R.string.sqlite_exception, Toast.LENGTH_SHORT).show();
return;
}
categories = dataSource.getAllCategories();
adapter = new CategoriesAdapter(this, categories);
rv_list_cats.setAdapter(adapter);
dataSource.close();

You need to override your onConfigurationChanged method in your activity or fragment and update your data there. Like.
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if(adapter!=null)
{
categories = dataSource.getAllCategories();
adapter.notifyDataSetChanged();
}
}
Also if you are not using the ScreenConfig property in your manifest use that looks like this.
android:configChanges="orientation|screenSize"

Related

android how to set particular item position for viewpager when onBackPressed()?

// Here is the adapter for viewpager
public void setupViewPager(){
pageAdapter = new PageAdapter(getSupportFragmentManager());
pageAdapter.addFragment(FragmentDesigns.newInstance(), "INDIAFILINGS");
icfo = ICFO.newInstance();
pageAdapter.addFragment(icfo, "iCFO PLATFORM");
viewPager.setAdapter(pageAdapter);
tabLayout.setupWithViewPager(viewPager);
// here code to set particular item in viewpager
int pageRedirect;
pageRedirect=CommonClass.getPageRedirect();
try {
if(pageRedirect!=0){
viewPager.setCurrentItem(1);
}
}catch (Exception e){
e.printStackTrace();
}
}
I am implementing viewpager with two fragments.In second Fragment i have list of data if user selects any item from a list it will redirect to another activity.If user does onbackPress in activity i want to set viewpager second fragment as a current fragment
Note:The issue is when i do onbackPress the application is getting close
#Override
public void onBackPressed() {
if (viewPager.getCurrentItem() != 0) {
viewPager.setCurrentItem(secondViewpagerItemPostion,false);
}else{
super.onBackPressed();
}
}
Store your current position of view pager in sharepref and check it if not null then viewpager.setCurrentItem(shareprefPosition);
override the onBackPressed method in your second activity so that system default behaviour does not happen
#Override
public void onBackPressed() {
Intent firstintent = new Intent(context,Firstactivity.class);
firstintent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(firstintent);
}
This will open the first activity, close the second activity and deliver the result in the onNewIntent of the first activity
In your first activity override onNewIntent so that the back press result is found
#Override
protected void onNewIntent(Intent intent) {
yourvp.setCurrentItem(positionyouneed);
}
This should do the trick for you

How to hide/show button in Android ListView dynamically

I have a listview with two buttons.
I want replace those two button with textview once I get the response from the server.
How can I achieve this?
After server response:
public void onResponse(String response) {
try {
JSONObject obj = new JSONObject(response);
if (obj.getString("response").equals("1")) {
JSONObject res = new JSONObject(obj.getString("data"));
Toast.makeText(getApplicationContext(), obj.getString("message"), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), obj.getString("message"), Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
I have not created any adapter.
you need to extend ArrayAdapter for customizing your listview items.
On your xml, keep both button and text views and for the textview, keep
android:visibility="gone"
initialize both textview and button in your adapter class. when you get the response, enable textview visibility and disable button visibility
textView.setVisilibity(View.VISIBLE);
button.setVisilibity(View.GONE);
ok i understand your problem and the best way is using recyclerview instead of listview , first of all see this example or recyclerview recyclerview example this is simple and best than normal listview ,
second in onBindViewHolder function you can create your own listner like this
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.your_sender_button.setonclickLinstener(new View.OnClickListener { #Override
public void onClick(View view) {
yourActivity.sendTimer(holder.btn1, your_sender_button, holder.your_textview_name);
}
});
}
sendTimer is the function used service to send the timer and the parameters is your views, so when you get the response set the visibility for these views you passed in your function

Refresh adapter in a Fragment after DialogFragment dbflow insert

I have an activity that has 3 fragments on it with Tabs, one of them is called "TaskFragment".
In my main Activity i only load the fragments.
In TaskFragment i have a RecyclerView that is working fine and is showing the items as intended.
The problem comes, when i insert data using a DialogFragment, because it does insert data (i am using DbFlow ORM), but it does not (of course) refresh the adapter since it is in the TaskFragment fragment inside the DetailMainActivity activity as i said.
I have tried to use onResume() and onPause() in order to refresh the adapter, but they are never called since the activity does not get paused or in onresume for a DialogFragment.
I have tried aswell to use an interface, but it does not work and i have searched all over stackoverflow and google with no luck.
I leave here some of my code for you to understand better:
DetailMainActivity.java
Here in the onClick interface i show the DialogFragment to the user to input the information.
FragmentManager fm = getSupportFragmentManager();
AddSimpleTask sptask = new AddSimpleTask();
sptask.show(fm, "tag");
TaskFragment.java
In this fragment i have my RecyclerView
private void setupRecyclerView() {
mRecyclerView.setAdapter(adapter);
mRecyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 2));
mRecyclerView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (DetailMainActivity.FAB_Status) {
DetailMainActivity.hideFAB();
DetailMainActivity.FAB_Status = false;
}
return false;
}
});
}
private void setupAdapter() {
adapter = new DetailMainTaskAdapter(simpleTaskList, this);
}
AddSimpleTask
And this is my DialogFragment. I have set a setOnShowListener() in order to avoid the DialogFragment to get dismiss early.
#Override
public void onShow(DialogInterface dialogInterface) {
final AlertDialog dialog =(AlertDialog) getDialog();
if (dialog != null){
Button positiveButton = dialog.getButton(Dialog.BUTTON_POSITIVE);
Button negativeButton = dialog.getButton(Dialog.BUTTON_NEGATIVE);
positiveButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mEditTextName.getText().toString().trim().isEmpty() ||
mEditTextContent.getText().toString().trim().isEmpty() ) {
if (mEditTextName.getText().toString().trim().isEmpty()) {
mEditTextName.setError("Can not be empty");
}
if (mEditTextContent.getText().toString().trim().isEmpty()) {
mEditTextContent.setError("Can not be empty");
}
}else {
presenter.beingInsertion(mEditTextName.getText().toString().trim(), mEditTextContent.getText().toString().trim()
, foreignId);
}
}
});
negativeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dismiss();
}
});
}
}
If the insert is successfully achieved the onInsertSuccess method is called (i am using MVP)
#Override
public void onInsertSuccess() {
Snackbar.make(getActivity().findViewById(R.id.containerMainDetail), "Actividad agregada", Snackbar.LENGTH_SHORT).show();
dismiss();
}
I have called adapter.notifyDataSetChanged() in many places, and i also tried with a custom interface, but i can not make this work.
Sorry for the long post, but thanks in advance for your help.
There are some errors in your statement but I'll get to that later. notifyDataSetChanged() only notifies the adapter that the underlying list (or array) has changed. The implication is that you first need to requery your database and obtain the new list before calling notifyDataSetChanged() on the adapter else there is no point as the underlying list will still be the same and it will not update the adapter.
The correct way of calling this will be through your custom listener interface and not in the onPause()/onResume() callbacks as there is the possibility that the user does not enter a value and hence you will unnecessarily be querying the database. In your custom listener interface implementation, first update the list with the new data from the DB and then notify the adapter.
Which leads to the error in assumption that onPause()/onResume() callbacks do not happen when your Activity is covered by a DialogFragment - this is incorrect. The moment the activity view is even partially covered, the onPause() callback is triggered.

Android multi-fragment layout in landscape mode

Although I got my code to work, I now have no idea what it's actually doing.
My app is an RSS reader, and the main content is in a Fragment containing a ListView with NewsStory objects. When a list item is clicked, it opens an Intent with the website linked from the RSS.
Now the problem is, I don't understand the Intent here, it's not the way I've ever used Intents before.
Also, I have to make it so that when I change the orientation, the original profile Fragment takes up the left half of the screen and the linked webpage takes up the right half of the screen. I've tinkered around with it, to no avail. I did a bit of research on orientation changes, but I feel like doing things with Fragments always changes how everything works. Anyway, here's the Fragment code. Any thoughts would be greatly appreciated.
public class HeadlineFragment extends Fragment {
EditText input;
Button search;
ListView headlines;
NewsDataSource ds;
public HeadlineFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_headline,container,false);
input = (EditText)v.findViewById(R.id.txtInput);
search = (Button)v.findViewById(R.id.btnSearch);
headlines = (ListView)v.findViewById(R.id.listView);
try {
ds = new NewsDataSource();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
headlines.setAdapter(new NewsDataSourceAdapter(this.getActivity(), ds));
headlines.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> parent,View view, int position, long id)
{
String url = NewsDataSource.stories[position].getLink();
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
}
});
return v;
}
/*
#Override
public void onConfigurationChanged(Configuration newConfig){
super.onConfigurationChanged(newConfig);
}
*/
}
Firstly, regarding that Intent, its an implicit Intent. When you set the action as ACTION_VIEW and add a URI / URL as an extra, the OS gets the message that you want to open an app that can navigate to that URI / URL.
Secondly, for showing a two-pane layout in landscape mode, you'll have to show that RSS content in a Fragment instead of an Activity as you are currently doing, and you'll have to display those Fragments side-by-side in an Activity in landscape mode. See the Retrieving a List of Contacts example for a really good explanation of how to display a multi-pane master detail layout in portrait mode.
References:
1. Intents and Intent Filters.
2. Planning for Multiple Touchscreen Sizes.

Change orientation without loading again

I want to change the orientation, but i have two different xml, one for portrait and the other one for landscape. The same information appear in the screen, except that it's moved to use some space. If i do :
android:configChanges="keyboardHidden|orientation"
It will only change from portrait to landscape in the same xml.
How can i change that ?
Set your view as a class variable:
private TextView yourView;
Add the following to the onCreate() method:
if (savedInstanceState != null) {
((TextView)findViewById(R.id.yourview)).restoreState(savedInstanceState);
}
And add an override on the saving of the instance state to save the state
#Override
protected void onSaveInstanceState(Bundle outState) {
yourView.saveState(outState);
}
Finally:
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
You should be able to manage config changes with this...
Override the onConfigurationChanged() method in your activity. Check the current orientation and set appropriate content view using setContentView().
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (newConfig.getConfiguration() == Configuration.ORIENTATION_LANDSCAPE) {
setContentView(landscape_layout);
} else {
setContentView(portrait_layout);
}
initViews();
}
In your Activity, override this method:
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
This will be triggered when orientation is changed. You can find out in what orientation you are using the parameter.
That's not how android works. If you want a different layout for portrait/landscape you must let the system handle the configuration change for you and load the appropriate layout xml.
Put this in your manifest
android:configChanges="orientation|keyboardHidden|screenSize|uiMode"
It solves mine and your problem :)

Categories

Resources