I am trying to refresh a RecyclerView by assigning a new adapter to the RecyclerView but it is throwing a NullPointerException.
I have created a TabLayout which has three tabs and when you reselect the first tab the method is called to refresh the RecyclerView. But, I am getting a NullPointerException on recyclerViewAdapter.notifyDataSetChanged();. I have initialized recyclerViewAdapter in the onCreateView(); but I still get an Exception.
EDIT :
This is a fragment not an Activity, I cannot setContentView();. Please read the question before down voting or doing anything not helpful.
Please suggest a proper way if I am doing it wrong.
Fragment which has the RecyclerView :
Tab1.class :
public class Tab1 extends Fragment {
private RecyclerView recyclerView;
private RecyclerViewAdapter recyclerViewAdapter;
private List<World> worldList;
private OnFragmentInteractionListener mListener;
private DBHelper helper;
private Context myContext;
private View view;
#Override
public void onStart() {
this.helper = new DBHelper(getContext());
recyclerViewAdapter = new RecyclerViewAdapter(getContext(), helper.getList());
super.onStart();
}
public Tab1() {
}
public void update() {
recyclerViewAdapter.notifyDataSetChanged();
}
#Override
public void onCreate(Bundle savedInstanceState) {
this.helper = new DBHelper(getContext());
this.worldList = new ArrayList<>();
this.worldList = helper.getList();
this.recyclerViewAdapter = new RecyclerViewAdapter(getContext(), this.worldList);
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_tab1, container, false);
recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerViewAdapter = new RecyclerViewAdapter(getContext(), worldList);
recyclerView.setAdapter(recyclerViewAdapter);
return view;
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnFragmentInteractionListener {
void onFragmentInteraction(Uri uri);
}
}
The method is called from the MainActivity.class(When the Tab is re selected).
MainActivty.class :
public class MainActivity extends AppCompatActivity implements Tab1.OnFragmentInteractionListener, Tab2.OnFragmentInteractionListener, Tab3.OnFragmentInteractionListener {
DBHelper helper;
World world;
Location location;
GPSTracker tracker;
RecyclerViewAdapter adapter;
public static Context CONTEXT = null;
RecyclerView recyclerView;
public Tab1 tab1;
public static final String BROADCAST_ACTION = "e.wolverine2.thewalkingapp";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 123);
CONTEXT = getApplicationContext();
MessageReciever reciever = new MessageReciever(new Message());
Intent intent = new Intent(this, MyService.class);
intent.putExtra("reciever", reciever);
startService(intent);
tracker = new GPSTracker(getApplicationContext());
location = tracker.getLocation();
helper = new DBHelper(getApplicationContext());
tab1 = new Tab1();
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
adapter = new RecyclerViewAdapter(getApplicationContext(), helper.getList());
final TabLayout tabLayout = (TabLayout) findViewById(R.id.myTabLayout);
tabLayout.addTab(tabLayout.newTab().setText("LOCATIONS"));
tabLayout.addTab(tabLayout.newTab().setText("TOTAL DISTANCE"));
tabLayout.addTab(tabLayout.newTab().setText("CALS"));
tabLayout.getTabAt(0).setIcon(R.drawable.ic_list);
tabLayout.getTabAt(1).setIcon(R.drawable.ic_person_pin);
tabLayout.getTabAt(2).setIcon(R.drawable.ic_fitness_excercise);
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
//onError();
final ViewPager viewPager = (ViewPager) findViewById(R.id.myViewPager);
final PagerAdapter pagerAdapter = new PagerAdapter(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(pagerAdapter);
viewPager.setOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
if (tab.getPosition() == 0) {
Tab1 tab1 = new Tab1();
tab1.update();
}
}
});
}
public void locationChanged(double longi, double lati) {
final Location location = new Location("");
location.setLatitude(lati);
location.setLongitude(longi);
world = new World();
String timeStamp = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss").format(new Date());
world.setLongitude(location.getLongitude());
world.setLatitiude(location.getLatitude());
world.setDate(timeStamp);
world.setTime(timeStamp);
world.setLocation("Anonymous");
helper.addRow(world);
//tab1.update(getApplicationContext());
}
#Override
public void onFragmentInteraction(Uri uri) {
}
public class Message {
public void displayMessage(int resultCode, Bundle resultData) throws NullPointerException {
double longi = resultData.getDouble("longitude");
double lati = resultData.getDouble("latitude");
locationChanged(longi, lati);
//Toast.makeText(MainActivity.this, "TOASTY X : " + e.getMessage(), Toast.LENGTH_SHORT).show();
//Log.v("TOASTY X : ","" + e.getMessage());
}
}
public void onError() {
helper.onDropTable();
Toast.makeText(this, "TABLE DROPED!", Toast.LENGTH_SHORT).show();
}
}
Logcat :
java.lang.NullPointerException: Attempt to invoke virtual method 'void e.wolverine2.thewalkingapp.RecyclerViewAdapter.notifyDataSetChanged()' on a null object reference
at e.wolverine2.thewalkingapp.Tab1.update(Tab1.java:57)
at e.wolverine2.thewalkingapp.MainActivity$1.onTabReselected(MainActivity.java:101)
at android.support.design.widget.TabLayout.dispatchTabReselected(TabLayout.java:1177)
at android.support.design.widget.TabLayout.selectTab(TabLayout.java:1136)
at android.support.design.widget.TabLayout.selectTab(TabLayout.java:1128)
at android.support.design.widget.TabLayout$Tab.select(TabLayout.java:1427)
at android.support.design.widget.TabLayout$TabView.performClick(TabLayout.java:1537)
at android.view.View$PerformClick.run(View.java:23985)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6816)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1563)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1451)
Java Tip: When it gets here:
Tab1 tab1 = new Tab1();
tab1.update();
A new Tab is instantiated using the cunstructor:
public Tab1() {
}
in your Tab class. as you see the recyclerView is not initialized up to this point.So the recyclerView is actually Null!
Answer: To correctly implement fragment take a look at this:
https://stackoverflow.com/a/5161143/6094503
What you looking for is the following lines:
Fragment newFragment = new DebugExampleTwoFragment();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.add(CONTENT_VIEW_ID, newFragment).commit();
but I think you need more study about fragments and how they're added to (or removed from) an activity
Related
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 3 years ago.
In my app, i have an activity that have recyclerview inside a fragment and the recycleview retrieve data from cloud store Firebase. I want to open new activity that will retrieve the data according to the link(that display on the recycler view) user has clicked.
How do i get the data and display it in new activity?
From ForumTitle.java > Show ReviewFragment.java > User click a value > Show ForumInterface.java
ForumTitle.java
public class ForumTitle extends AppCompatActivity {
private FirebaseFirestore db = FirebaseFirestore.getInstance();
ImageButton IVReview,IVTechnical,IVHardware;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_forum_title);
View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View v) {
Fragment selectedFragment = null;
if (v == findViewById(R.id.iBReview)){
selectedFragment = new ReviewFragment();
}
else if (v == findViewById(R.id.iBTech)){
selectedFragment = new TechnicalSupportFragment();
}
else if (v == findViewById(R.id.iBHardware)){
selectedFragment = new HardwareFragment();
}
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.fragment_container,selectedFragment);
transaction.commit();
}
};
IVReview = (ImageButton)findViewById(R.id.iBReview);
IVTechnical = (ImageButton)findViewById(R.id.iBTech);
IVHardware = (ImageButton)findViewById(R.id.iBHardware);
IVReview.setOnClickListener(listener);
IVTechnical.setOnClickListener(listener);
IVHardware.setOnClickListener(listener);
}
}
ReviewFragment.java
public class ReviewFragment extends Fragment {
private FirebaseFirestore db = FirebaseFirestore.getInstance();
private CollectionReference userRef = db.collection("Review");
private ForumAdapter adapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_review,container,false);
return view;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
Query query = userRef.orderBy("DatePosted",Query.Direction.DESCENDING);
FirestoreRecyclerOptions<Forum> options = new
FirestoreRecyclerOptions.Builder<Forum>()
.setQuery(query,Forum.class)
.build();
adapter = new ForumAdapter(options);
RecyclerView recyclerView = (RecyclerView)view.findViewById(R.id.rvReview);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this.getActivity());
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
adapter.setOnItemClickListener(new ForumAdapter.OnItemClickListener() {
#Override
public void onItemClick(DocumentSnapshot documentSnapshot, int position) {
Forum forum = documentSnapshot.toObject(Forum.class);
String title = forum.getTitle();
String id = documentSnapshot.getId();
Intent intent = new Intent(getActivity(), ForumInterface.class);
Bundle extras = intent.getExtras();
extras.putString("FORUM_TYPE","Review");
extras.putString("FORUM_ID",id);
extras.putString("TITLE",title);
startActivity(intent);
}
});
}
#Override
public void onStart() {
super.onStart();
adapter.startListening();
}
#Override
public void onStop() {
super.onStop();
adapter.stopListening();
}
ForumInterface.java
public class ForumInterface extends AppCompatActivity {
private FirebaseFirestore db = FirebaseFirestore.getInstance();
Intent intent = getIntent();
Bundle extras = intent.getExtras();
String forum_title = extras.getString("TITLE");
String forum_type = extras.getString("FORUM_TYPE");
String forum_id = extras.getString("FORUM_ID");
private CollectionReference userRef = db.collection(forum_type).document(forum_id).collection(forum_title);
private ForumAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_forum_interface);
TextView test = (TextView)findViewById(R.id.tvForumTitle);
test.setText(forum_title);
}
}
ForumAdapter.java
public class ForumAdapter extends FirestoreRecyclerAdapter<Forum,ForumAdapter.ForumHolder> {
private OnItemClickListener listener;
public ForumAdapter(FirestoreRecyclerOptions<Forum> options) {
super(options);
}
#Override
public void onBindViewHolder(ForumHolder forumHolder, int i, Forum forum) {
forumHolder.textViewTitle.setText(forum.getTitle());
forumHolder.textViewDescription.setText(forum.getDescription());
forumHolder.timeStamp.setText(forum.getDatePosted().toString());
}
#NonNull
#Override
public ForumHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
android.view.View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.cardviewforumtitle,parent,false);
return new ForumHolder(v);
}
class ForumHolder extends RecyclerView.ViewHolder{
TextView textViewTitle;
TextView textViewDescription;
TextView timeStamp;
public ForumHolder(View itemView) {
super(itemView);
textViewTitle = itemView.findViewById(R.id.title);
textViewDescription = itemView.findViewById(R.id.description);
timeStamp = itemView.findViewById(R.id.timestamp);
textViewTitle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int position = getAdapterPosition();
// NO_POSITION to prevent app crash when click -1 index
if(position != RecyclerView.NO_POSITION && listener !=null ){
listener.onItemClick(getSnapshots().getSnapshot(position),position);
}
}
});
}
}
public interface OnItemClickListener{
void onItemClick(DocumentSnapshot documentSnapshot, int position);
}
public void setOnItemClickListener(OnItemClickListener listener){
this.listener = listener;
}
#Override
public int getItemCount() {
return super.getItemCount();
}
}
With the code above i run it, i got an error
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.os.Bundle.putString(java.lang.String, java.lang.String)' on a null object reference
at my.edu.fsktm.um.finalproject.Fragment.ReviewFragment$1.onItemClick(ReviewFragment.java:61)
at my.edu.fsktm.um.finalproject.ForumTitle.ForumAdapter$ForumHolder$1.onClick(ForumAdapter.java:56)
The picture of my app
When I clicked the title "GTX 1660 Ti Gaming X"
You try to set content on a Bundle which is null in your ReviewFragment's onClick. Use new Bundle() instead of intent.getExtras(); to instantiate Bundle
Bundle extras = new Bundle();
extras.putString("FORUM_TYPE","Review");
extras.putString("FORUM_ID",id);
extras.putString("TITLE",title);
//You have to set the bundle to intent
intent.putExtras(extras);
startActivity(intent);
Beside this move below code inside onCreate of ForumInterface Activity
Intent intent = getIntent();
Bundle extras = intent.getExtras();
String forum_title = extras.getString("TITLE");
String forum_type = extras.getString("FORUM_TYPE");
String forum_id = extras.getString("FORUM_ID");
And here is the complete Activity.
public class ForumInterface extends AppCompatActivity {
private FirebaseFirestore db;
private CollectionReference userRef;
private ForumAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_forum_interface);
Intent intent = getIntent();
Bundle extras = intent.getExtras();
String forum_title = extras.getString("TITLE");
String forum_type = extras.getString("FORUM_TYPE");
String forum_id = extras.getString("FORUM_ID");
db = FirebaseFirestore.getInstance();
userRef = db.collection(forum_type).document(forum_id).collection(forum_title);
TextView test = (TextView)findViewById(R.id.tvForumTitle);
test.setText(forum_title);
}
}
I'm trying to update my WebView in a Fragment when RecyclerView Item is clicked. In the debug console it's printing my hard-coded URL, but it's not updating the View - it is staying on "Google" webpage without any changes, but seems like onClickListener is working.
MainActivity.java
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Add Websites
ArrayList<Website> websitesList = new ArrayList<>();
websitesList.add(new Website(R.drawable.ic_launcher_background, "Line 1", "https://google.com/"));
websitesList.add(new Website(R.drawable.ic_launcher_background, "Line 2", "https://yahoo.com/"));
websitesList.add(new Website(R.drawable.ic_launcher_background, "Line 3", "https://abv.bg/"));
mRecyclerView = findViewById(R.id.recyclerView);
mLayoutManager = new LinearLayoutManager(this);
mAdapter = new WebsiteAdapter(websitesList);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
}
public void switchContent(int id, Fragment fragment) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(id, fragment);
ft.commit();
}
}
RecyclerView Adapter
#Override
public void onBindViewHolder(#NonNull ExampleViewHolder holder, int position) {
final Website currentItem = mWebsiteList.get(position);
holder.mImageView.setImageResource(currentItem.getImage());
holder.mTitle.setText(currentItem.getTitle());
holder.mTitle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
fragmentJump(currentItem);
}
});
}
#Override
public int getItemCount() {
return mWebsiteList.size();
}
private void fragmentJump(Website mItemSelected) {
Fragment mFragment = new WebsiteView();
Bundle mBundle = new Bundle();
mBundle.putString("url", "http://facebook.com/");
mFragment.setArguments(mBundle);
switchContent(R.id.fragment, mFragment);
}
public void switchContent(int id, Fragment fragment) {
if (mContext == null)
return;
if (mContext instanceof MainActivity) {
MainActivity mainActivity = (MainActivity) mContext;
mainActivity.switchContent(id, fragment);
}
}
WebView Fragment
private WebView webView;
String mUrl;
public WebsiteView() {}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_website_view, container, false);
try {
mUrl = getArguments().getString("url");
} catch(Exception ex) {
System.out.println(ex.toString());
mUrl = "http://google.com/";
}
System.out.println(mUrl);
webView = v.findViewById(R.id.webView);
webView.setWebViewClient(new WebViewClient());
webView.loadUrl(mUrl);
return v;
}
Okay, it appeared that I'm actually trying to update the Fragment data, and when I replace another fragment with my desired one it works. Any ideas how to update the WebView in the fragment?
Not able to pass the retrived list of data from retrofit to a recyclerview in fragment!
Tried some solutions but not working!
I have tried creating methods in fragment and passing but not working!
Getting null!
Activity
TabLayout tabLayout;
ViewPager viewPager;
RecyclerView recyclerView;
//vars
private Dto dto;
List<Post_DTO> post_dto_list=new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState)
{
dto=new Dto();
UpdateList();
super.onCreate(savedInstanceState);
setContentView(R.layout.home_layout);
tabLayout=(TabLayout)findViewById(R.id.tabLayout);
viewPager=(ViewPager)findViewById(R.id.viewPager);
tabLayout.addTab(tabLayout.newTab().setText("Dashboard"));
tabLayout.addTab(tabLayout.newTab().setText("Converations"));
tabLayout.addTab(tabLayout.newTab().setText("Profile"));
PostFragment pf=new PostFragment();
pf.passData(getApplicationContext(),post_dto_list);
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
//ft.add(R.id.posts_recyclerview, ft);
ft.addToBackStack(null);
ft.commit();
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
final MyAdapter adapter = new MyAdapter(this,getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
System.out.println(tab.getPosition());
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
private void UpdateList() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(getString(R.string.postUrl))
.addConverterFactory(GsonConverterFactory.create())
.build();
PostsInterface postsInterface =retrofit.create(PostsInterface.class);
Call<Post_DTO_Resp> call= postsInterface.getPosts();
call.enqueue(new Callback<Post_DTO_Resp>() {
#Override
public void onResponse(Call<Post_DTO_Resp> call, Response<Post_DTO_Resp> response) {
//pDialog.dismiss();
if(!response.isSuccessful())
{
Toast.makeText(getApplicationContext(),"Loading the posts!",Toast.LENGTH_SHORT).show();
}
Post_DTO_Resp posts = response.body();
post_dto_list=posts.getPost_dto_list();
//dto.setList(post_dto_list);
}
#Override
public void onFailure(Call<Post_DTO_Resp> call, Throwable t) {
//pDialog.dismiss();
if(t.getMessage().equals("End of input at line 1 column 1 path $"))
{
Toast.makeText(getApplicationContext(), "There are no posts!", Toast.LENGTH_LONG).show();
}
else
{
Toast.makeText(getApplicationContext(), "Api Error!", Toast.LENGTH_LONG).show();
}
}
});
}
}
Fragment!
public class PostFragment extends Fragment {
RecyclerView recyclerView;
View v;
Dto dtobject;
private static final String DESCRIBABLE_KEY = "list";
private Describable mDescribable;
List<Post_DTO> post_dto_list;
public PostFragment() {
// Required empty public constructor
}
public void passData(Context context, List<Post_DTO> list) {
//mContext = context;
post_dto_list = list;
// mIndex = pos;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
v=inflater.inflate(R.layout.fragment_posts, container, false);
recyclerView=(RecyclerView) v.findViewById(R.id.posts_recyclerview);
RecyclerViewAdapter recyclerViewAdapter=new RecyclerViewAdapter(getContext(),post_dto_list);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setAdapter(recyclerViewAdapter);
//listupdater();
return v;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
Just want to get the post_dto_list from Activity to fragment class!
Suggestions please!
You can use a bundle to pass a list from activity to fragment.
In activity:
Bundle bundle = new Bundle();
bundle.putSerializable("list", mList);
mFragment.setArguments(bundle);
And then in your fragment:
mList = getIntent().getExtras().getSerializable("list"));
But the POJO that your list contains should be parcelable ( Parcelable better than Serializable).
Your POJO should be something like:
public class MyPOJO implements Parcelable {
For more info refer this.
I got a problem with updating ViewPager fragments. We need to show fragments with data to registered user, when he doesn't registered we need to show fragments with message to register. I use this method to check it in MainActivity:
#Override
public void setAdapter(boolean isUserExist) {
Log.d("RegDebug", "In setAdapter");
mainPagerAdapter.clearData();
mainPagerAdapter.addFragment(searchFragment, getString(R.string.search_title));
if (isUserExist) {
Log.d("RegDebug", "In setAdapter reg");
mainPagerAdapter.addFragment(new ChatsFragment(), getString(R.string.chats_title));
mainPagerAdapter.addFragment(new ActionsFragment(), getString(R.string.actions_title));
Toast.makeText(getApplicationContext(), "Registered!", Toast.LENGTH_SHORT).show();
} else {
Log.d("RegDebug", "In setAdapter unreg");
mainPagerAdapter.addFragment(RegisterFragment.newInstance(Consts.CHATS_TAB_NAME), getString(R.string.chats_title));
mainPagerAdapter.addFragment(RegisterFragment.newInstance(Consts.ACTIONS_TAB_NAME), getString(R.string.actions_title));
Toast.makeText(getApplicationContext(), "Unregistered!!!", Toast.LENGTH_SHORT).show();
}
mainPagerAdapter.notifyDataSetChanged();
viewPager.setAdapter(mainPagerAdapter);
}
I call this method in presenter with setting value from firebase auth, checking if user exists:
public void checkForUserExist() {
if (mainInteractor.isUserExist()) {
getViewState().setRegAdapter();
} else getViewState().setUnregAdapter();
}
And then call presenter method in onCreate of MainActivity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dialogFragment = new FilterDialogFragment();
searchFragment = new SearchFragment();
//UI
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
viewPager = findViewById(R.id.main_view_pager);
tabLayout = findViewById(R.id.main_tabs);
//mainPagerAdapter = new MainPagerAdapter(getSupportFragmentManager());
mainPresenter.checkForUserExist();
tabLayout.setupWithViewPager(viewPager);
}
I try to log the boolean result and it returns exactly value that must be, but pager adapter can't update its content.Code of MainPagerAdapter:
public class MainPagerAdapter extends FragmentPagerAdapter{
private final List<Fragment> fragmentList = new ArrayList<>();
private final List<String> fragmentTitleList = new ArrayList<>();
public MainPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
#Override
public int getCount() {
return fragmentTitleList.size();
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
return fragmentTitleList.get(position);
}
public void addFragment(Fragment fragment, String title){
fragmentList.add(fragment);
fragmentTitleList.add(title);
}
public void clearData(){
fragmentList.clear();
fragmentTitleList.clear();
notifyDataSetChanged();
Log.d("RegDebug", " fragmentList size is " + fragmentList.size()
+ " fragmentTitleList size is " + fragmentTitleList.size());
}
}
Use OnPageChangeListener of ViewPager class & notify to your current fragment from there using interface.
I'm making a simple app that adds a location to the list fragment in main page, and as I add more addresses to the list, whenever configuration changes, those addresses are carried over, which is expected.
However as you will see below, the empty list text shows up for some reason, and seems like when I add another new address hereafter, it will add to the very first place of the list.
Below is my main activity :
public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
private GoogleApiClient mGoogleApiClient;
private Location mLastLocation, mCurrentLocation;
private double currentLatitude, currentLongitude;
private String lastUpdateTime, addressMessage = null;
private AddressResultReceiver resultReceiver;
private MainList listFragment = new MainList();
//private boolean mRequestStatus = true;
private MaterialDialog dialog;
public boolean mAddressRequested = false;
private FragmentManager mFragmentManager;
private final String FRAGMENT_TAG = "main_list_tag";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addOnConnectionFailedListener(this)
.addConnectionCallbacks(this)
.build();
mFragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
fragmentTransaction.add(R.id.list_frame, listFragment);
fragmentTransaction.commit();
dialog = new MaterialDialog(this)
.setTitle("Select an address")
.setPositiveButton("SELECT", new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
listFragment.list.add(addressMessage);
listFragment.mAdapter.notifyDataSetChanged();
}
})
.setNegativeButton("CANCEL", new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
}
});
Toolbar toolbar = (Toolbar) findViewById(R.id.tool_bar);
setSupportActionBar(toolbar);
FloatingActionButton floatingActionButton = (FloatingActionButton) findViewById(R.id.fab_button);
//LayoutInflater inflater = LayoutInflater.from(getApplicationContext());
floatingActionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (checkAirPlaneMode(getApplicationContext())) {
Toast.makeText(getApplicationContext(), "Air Plane Mode is ON, Please turn off to get location", Toast.LENGTH_LONG).show();
}
else if (!checkNetwork()) {
Toast.makeText(getApplicationContext(),"Unable to reach network, please check network settings",Toast.LENGTH_LONG).show();
}
else if (!checkLocationSettings(getApplicationContext())) {
showLocationSettings();
}
else {
startAddressLookUp();
mAddressRequested = true;
dialog.setMessage(addressMessage);
dialog.show();
}
}
});
}
#Override
public void onStart() {
super.onStart();
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addOnConnectionFailedListener(this)
.addConnectionCallbacks(this)
.build();
}
mGoogleApiClient.connect();
}
#Override
protected void onPause() {
super.onPause();
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
#Override
public void onResume() {
super.onResume();
if(mGoogleApiClient.isConnected()) {
LocationRequest locationRequest = createLocationRequest();
startLocationUpdates(locationRequest);
}
}
And list fragment class:
public class MainList extends ListFragment implements AdapterView.OnItemClickListener {
private int stateInt;
private final String FRAGMENT_KEY = "saved_fragment";
ArrayList<String> list = new ArrayList<>();
ArrayAdapter<String> mAdapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.list_fragment, container, false);
/*ListView view = (ListView) v.findViewById(android.R.id.list);
view.setEmptyView(v.findViewById(android.R.id.empty));
return view;*/
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setRetainInstance(true);
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
mAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, list);
setListAdapter(mAdapter);
//mAdapter.notifyDataSetChanged();
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(parent.getContext(), "Item Pressed!", Toast.LENGTH_LONG).show();
}
}
How can avoid this? Am I missing the save application state or something else? Any help would be appreciated! Thanks in advance!
Thanks,
Paul
The onCreate method is called for every orientation change. And in the method you are adding the fragment again. That is why you get this behavior.
Check this for the correct way to do this.
Handling Configuration Changes with Fragments
FragmentManager fm = getFragmentManager();
mTaskFragment = (TaskFragment) fm.findFragmentByTag(TAG_TASK_FRAGMENT);
// If the Fragment is non-null, then it is currently being
// retained across a configuration change.
if (mTaskFragment == null) {
mTaskFragment = new TaskFragment();
fm.beginTransaction().add(mTaskFragment, TAG_TASK_FRAGMENT).commit();
}