Android: How can I add Google map to a ViewPager? - java

I want to make an app that has on the main screen a ViewPager with a map and a profile section. Therefore, for position = 0 in the ViewPager, there is the map and for position = 1, there is the profile.
For each one of those two "sections" on the main screen, I have two activities: the map.xml with the MapActivity.java and the profile.xml with Profile.java. Both of those are inflated in the EnumFrag java class, depending on the position ( you see there an if ).
I have two issues:
The first one is that when I try to slide left or right, the map moves, not the ViewPager to the next slide. I tried to put a shape on the edge, but it is not working like the slide gesture is passing through the shape. Any help here, please?
The second is related to the first one, the MapActivity.java class is not even running because onCreate is not running (I put a Toast there so display something and nothing happened). Any help, please? (I create the map class object).
map.xml contains a simple fragment with an id of map.
MapActivity.java:
public class MapActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap map;
private Location me;
private FusedLocationProviderClient fusedLocationProviderClient;
private static final int REQUEST_CODE = 101;
#Override
protected void onCreate(Bundle savedInstanceState) {
Toast.makeText(this, "hey din onCreate", Toast.LENGTH_SHORT).show();
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
getLastLocation();
}
private void getLastLocation() {
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION},REQUEST_CODE);
return;
}
Toast.makeText(getApplicationContext(), "hey...", Toast.LENGTH_SHORT).show();
Task<Location> task = fusedLocationProviderClient.getLastLocation();
task.addOnSuccessListener(new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
if(location != null){
me = location;
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(MapActivity.this);
}
else
Toast.makeText(getApplicationContext(), "Deschide-ti locatia", Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void onMapReady(GoogleMap googleMap) {
map = googleMap;
MapStyleOptions mapStyleOptions= MapStyleOptions.loadRawResourceStyle(this,R.raw.map_style);
googleMap.setMapStyle(mapStyleOptions);
LatLng point = new LatLng(me.getLatitude(),me.getLongitude());
MarkerOptions markerOptions = new MarkerOptions().position(point).title("Me");
googleMap.animateCamera(CameraUpdateFactory.newLatLng(point));
googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(point,16));
googleMap.addMarker(markerOptions);
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if (requestCode == REQUEST_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
getLastLocation();
}
}
}
}
Profile.java
public class Profile extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
EditText username = findViewById(R.id.usernameProfile);
username.setText(MainScreen.getUsername());
}
}
EnumFragment.java
public class EnumFragments extends PagerAdapter {
private Context context;
public EnumFragments(Context context) {
this.context = context;
}
#NonNull
#Override
public Object instantiateItem(#NonNull ViewGroup container, int position) {
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view;
MapActivity mapActivity = new MapActivity();
switch (position){
case 0:
view = layoutInflater.inflate(R.layout.activity_profile,null);
break;
default:
view = layoutInflater.inflate(R.layout.activity_map,null);
break;
}
ViewPager viewPager = (ViewPager)container;
viewPager.addView(view);
return view;
}
#Override
public void destroyItem(#NonNull ViewGroup container, int position, #NonNull Object object) {
ViewPager viewPager = (ViewPager)container;
View view = (View) object;
viewPager.removeView(view);
}
#Override
public int getCount() {
return 2;
}
#Override
public boolean isViewFromObject(#NonNull View view, #NonNull Object object) {
return view == object;
}
}
MainScreen.java
public class MainScreen extends AppCompatActivity {
private static String username;
private ViewPager viewPager;
private EnumFragments enumFragments;
private static int userID;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_screen);
Bundle extras = getIntent().getExtras();
userID = extras.getInt("userID");
username = extras.getString("username");
viewPager = findViewById(R.id.mainSlider);
EnumFragments enumFragments = new EnumFragments(this);
viewPager.setAdapter(enumFragments);
}
public static int getUserID() {
return userID;
}
public static String getUsername() {
return username;
}
#Override
public void onBackPressed() {
//Nothing
}
}

Why you don't add the MapActivity into the MainScreen Activity. You even don't use the MapActivity in your PagerAdapter class. I would make an other attribute in the constructor of your PagerAdapter, after this :
private MapActivity current;
public EnumFragments(MapActivity map_activity)
{
this.current = map_activity;
}
then I would put a getter method in the map_activity, wich returns a view, where you can see the current GoogleMap or other features.
Your problem is that you don't use the new MapActivity...
I hope that may helps you

Related

RecyclerView disappearing after switching between fragments on a particular Activity

The problem I have been facing with the development is that there is a recyclerview inside my fragment which gets disappeared after I switch between two fragments on a particular activity. On the first time when the fragment loads everything works fine but afterwards I don't understand what goes wrong. I had tried to refer to various ways that people had posted over github like notifyDatasetChanged, etc. But nothing seems to work. I would appreciate if someone could help me out with this issue.
So here are my classes.
The ProfileFragment.java :
public class ProfileFragment extends Fragment {
FirebaseAuth firebaseAuth;
FirebaseUser user;
FirebaseDatabase firebaseDatabase;
DatabaseReference databaseReference;
StorageReference storageReference;
RecyclerView itemRecycler;
List<ModelProfile> modelProfiles;
AdapterProfile adapterProfile;
String storagePath= "Users_Profile_Cover_Image/-";
ImageView avatarIv,dp;
CardView card,cardArrow;
TextView nameTv, emailTv, phoneTv;
Button logout,update;
ExtendedFloatingActionButton fab;
ProgressDialog pd;
//..
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
final View view= inflater.inflate(R.layout.fragment_profile, container, false);
firebaseAuth = FirebaseAuth.getInstance();
user= firebaseAuth.getCurrentUser();
firebaseDatabase = FirebaseDatabase.getInstance();
databaseReference = firebaseDatabase.getReference("Users");
storageReference= getInstance().getReference();
loadItems();
return view;
}
private void loadItems() {
//Problem could be here
GridLayoutManager layoutManager= new GridLayoutManager(getContext(),3);
itemRecycler.setHasFixedSize(true);
itemRecycler.setLayoutManager(layoutManager);
itemRecycler.setVisibility(View.VISIBLE);
CollectionReference ref =FirebaseFirestore.getInstance().collection("All_Posts");
com.google.firebase.firestore.Query query = ref.whereEqualTo("uid",uid);
FirestoreRecyclerOptions<ModelProfile> options = new FirestoreRecyclerOptions.Builder<ModelProfile>()
.setQuery(query,ModelProfile.class).build();
adapterProfile = new AdapterProfile(options,getActivity());
itemRecycler.setAdapter(adapterProfile);
adapterProfile.startListening();
query.addSnapshotListener(new EventListener<QuerySnapshot>() {
#Override
public void onEvent(#Nullable QuerySnapshot value,
#Nullable FirebaseFirestoreException e) {
if (e != null) {
return;
}
assert value != null;
Log.i("Size",String.valueOf(value.getDocuments().size()));
if (value.getDocuments().size() > 0) { // List is populated
card.setVisibility(View.GONE);
cardArrow.setVisibility(View.GONE);
} else { // List is empty
card.setVisibility(View.VISIBLE);
cardArrow.setVisibility(View.VISIBLE);
}
}
});
}
//
// #Override
// public void onStart() {
// super.onStart();
// adapterProfile.startListening();
// }
//
//
//
// #Override
// public void onStop() {
// super.onStop();
// adapterProfile.stopListening();
// }
#Override
public void onResume() {
super.onResume();
adapterProfile.startListening();
}
}
Adapter:-
public class AdapterProfile extends FirestoreRecyclerAdapter<ModelProfile,AdapterProfile.MyHolder> {
Context context;
public String im;
public AdapterProfile(#NonNull FirestoreRecyclerOptions<ModelProfile> options, Activity Context) {
super(options);
context = Context;
}
#Override
protected void onBindViewHolder(#NonNull MyHolder holder, int position, #NonNull ModelProfile model) {
String uid = model.getUid();
String uEmail =model.getuEmail();
}
#NonNull
#Override
public MyHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
//..
}
class MyHolder extends RecyclerView.ViewHolder{
//..
}
Activity on which Fragment switching takes place
public class LandingActivity extends AppCompatActivity {
FirebaseAuth firebaseAuth;
DatabaseReference userDbRef;
FirebaseUser user;
String uid,dp;
ChipNavigationBar chipNavigationBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_landing);
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,new InventoryFragment()).commit();
bottomMenu();
}
private void bottomMenu() {
chipNavigationBar.setOnItemSelectedListener(new ChipNavigationBar.OnItemSelectedListener() {
//problem could be here as well.........
#Override
public void onItemSelected(int i) {
Fragment fragment=null;
switch(i) {
case R.id.bottom_nav_2:
fragment = new CltFragment();
break;
case R.id.bottom_nav_3:
fragment = new MaceFragment();
break;
case R.id.bottom_nav_profile:
fragment = new ProfileFragment();
break;
}
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,fragment).commit();
}
});
}
private void checkUserStatus()
{
FirebaseUser user= firebaseAuth.getCurrentUser();
if(user !=null)
{
uid=user.getUid();
}
else
{
startActivity(new Intent(LandingActivity.this,MainActivity.class));
finish();
}
}
#Override
public void onResume() {
//Problem could be here
super.onResume();
Intent intent = getIntent();
String frag = "";
if(intent.hasExtra("frag")) {
frag = intent.getExtras().getString("frag");
}
else
{
//..
}
switch(frag)
{
//..
case "ProfileFragment":
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ProfileFragment()).commit();
chipNavigationBar.setItemSelected(R.id.bottom_nav_profile,true);
break;
}
}
}
Thanks for having looked at my Problem!
Try using this
getSupportFragmentManager().beginTransaction().add(R.id.fragment_container,new InventoryFragment()).commit();
Instead of this
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,new InventoryFragment()).commit();

How do I send data from fragment to another activity [duplicate]

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);
}
}

ViewPager doesn't update added fragments

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.

Android Studio: NullPointerException when trying to click on a object in a list and start a new activity

I have a Room database, containing a list of members. There are different members in a list. I want to click on a specific member and then it should start a new activity where I can see additional information about that member. But when I click on a member, the app crashes.
Code of my adapter:
public class MemberListAdapter extends RecyclerView.Adapter<MemberListAdapter.MemberViewHolder> {
private List<Member> mMember;
private MemberClickListener listener;
public interface MemberClickListener {
void onMemberClick(int position);
}
public MemberListAdapter(final MemberClickListener listener) {
this.listener = listener;
}
#Override
public MemberViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_member, parent, false);
return new MemberViewHolder(itemView, listener);
}
void setMember(List<Member> members) {
mMember = members;
notifyDataSetChanged();
}
#Override
public int getItemCount() {
if (mMember != null)
return mMember.size();
else return 0;
}
#Override
public void onBindViewHolder(MemberViewHolder holder, int position) {
holder.bind(mMember.get(position), listener);
}
class MemberViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private final MemberClickListener listener;
private final TextView firstname;
private final TextView surname;
private final TextView balance;
MemberViewHolder(View itemView, MemberClickListener listener) {
super(itemView);
firstname = itemView.findViewById(R.id.layout_firstname);
surname = itemView.findViewById(R.id.layout_surname);
balance = itemView.findViewById(R.id.layout_balance);
this.listener = listener;
itemView.setOnClickListener(this);
}
public void bind(final Member member, final MemberClickListener listener) {
firstname.setText(member.getFirstname());
surname.setText(member.getSurname());
//balance.setText(toString(member.getBalance()));
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.i("test1", "beforelistenercheck");
if (listener != null) {
Log.i("test2", "duringlistenercheck");
listener.onMemberClick(getAdapterPosition());
Log.i("test3", "aftergettingposition");
}
}
});
}
public void onClick(View v) {
if (listener != null) {
********listener.onMemberClick(getAdapterPosition());********
}
}
}
}
Code of my main activity:
public class MemberMainActivity extends AppCompatActivity implements MemberListAdapter.MemberClickListener{
private MemberViewModel mMemberViewModel;
private List<Member> mMember;
void setMember(List<Member> members) {
mMember = members;
}
public static final int NEW_MEMBER_ACTIVITY_REQUEST_CODE = 1;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_member);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MemberMainActivity.this, NewMemberActivity.class);
startActivityForResult(intent, NEW_MEMBER_ACTIVITY_REQUEST_CODE);
}
});
RecyclerView recyclerView = findViewById(R.id.recyclerviewcard_member);
final MemberListAdapter adapter = new MemberListAdapter(this);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
mMemberViewModel = ViewModelProviders.of(this).get(MemberViewModel.class);
mMemberViewModel.getAllMember().observe(this, new Observer<List<Member>>() {
#Override
public void onChanged(#Nullable final List<Member> members) {
// Update the cached copy of the words in the adapter.
adapter.setMember(members);
}
});
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == NEW_MEMBER_ACTIVITY_REQUEST_CODE && resultCode == RESULT_OK) {
Member member = new Member(data.getStringExtra(NewMemberActivity.EXTRA_REPLY), data.getStringExtra(NewMemberActivity.EXTRA_REPLY2));
mMemberViewModel.insert(member);
} else {
Toast.makeText(
getApplicationContext(),
R.string.empty_not_saved,
Toast.LENGTH_LONG).show();
}
}
public void onMemberClick(int position) {
**********Member member = mMember.get(position);**********
MemberInfo.open(this, member.getId());
}
}
Code of the activity which should be launched after clicking on a member:
public class MemberInfo extends AppCompatActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_memberinfo);
Intent intent = getIntent();
if (intent != null && intent.hasExtra("MemberID")) {
long memberid = intent.getLongExtra("MemberID", -1);
// TODO: get customer details based on customer id
Bundle bundle = new Bundle();
bundle.putLong("MemberID", memberid);
intent.putExtras(bundle);
startActivity(intent);
}
else {
Toast.makeText(
getApplicationContext(),
R.string.empty_not_saved,
Toast.LENGTH_LONG).show();
}
}
public static void open(Activity activity, long memberid) {
Intent intent = new Intent(activity, MemberInfo.class);
intent.putExtra("MemberID", memberid);
activity.startActivity(intent);
}
}
The error:
logcat: java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.Object java.util.List.get(int)' on a null object reference
at com.example.ahash.mainbuchhaltung.Member.MemberMainActivity.onMemberClick(MemberMainActivity.java:81)
at com.example.ahash.mainbuchhaltung.Member.MemberListAdapter$MemberViewHolder$1.onClick(MemberListAdapter.java:86)
at android.view.View.performClick(View.java:6256)
at android.view.View$PerformClick.run(View.java:24701)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
I marked the lines, where the error is, with stars.
I also tried to solve my problem with the answers to this question: What is a NullPointerException, and how do I fix it?
I have three different Logs in my adapter code, named "test1", "test2" and "test3". I emulated my app and "test1" and "test2" were shown in my logcat, but "test3" wasn't shown.
I have been working on this for three weeks, and I'm still standing at the same problem as before. Can anyone help me to solve this problem?
your mMember is null inside the onMemberClick method.
I have created a new project using your code, and you forgot to initialize your list of member called "mMember".
I created a method to load fake members and everything is working without problems.
Example:
private void loadFakeData(){
mMember = new ArrayList<>();
Member newMember;
for (int i = 0; i < 10; i++) {
newMember = new Member();
newMember.setFirstName("Firstname " + i);
newMember.setSurName("Surname " + i);
mMember.add(newMember);
}
mAdapter.setMember(mMember);
}
Your private List<Member> mMember in your main activity is not initialized when you acess it (most likely in the listener).
You could make it private List<Member> mMember = new ArrayList<Member(); instead and have at least an empty list.
As an alternative, you could insert mMember = new ArrayList<Member>(); somewhere before mMemberViewModel.getAllMember().observe(this, new Observer<List<Member>>() in onCreate().

Android list fragment not updated when configuration changes

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();
}

Categories

Resources