I made this switch on one of my fragment to switch from the dark theme to light theme. The only problem is that when I leave fragment with the switch on when I go back to the fragment, the switch is off instead of being on like I left it.
Here are the images.
When I go on the fragment: Fragment Switch Off
When I flip the switch: Fragment Switch On
Then I leave the Fragment, then come back to the Fragment: Fragment Switch off while supposed to be on
Her is my code:
SettingsFragment.java:
package com.barzalou.lpapineau.test.ui.settings;
import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.Switch;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProviders;
import com.barzalou.lpapineau.test.R;
import com.barzalou.lpapineau.test.ui.CheckedChangeCallback;
import java.util.Objects;
public class SettingsFragment extends Fragment {
private SettingsViewModel settingsViewModel;
private CheckedChangeCallback callback = null;
public void onAttach(final Activity activity) {
super.onAttach(activity);
if (activity instanceof CheckedChangeCallback) {
this.callback = (CheckedChangeCallback) activity;
}
}
public void onDetach() {
super.onDetach();
callback = null;
}
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
settingsViewModel = ViewModelProviders.of(this).get(SettingsViewModel.class);
View root = inflater.inflate(R.layout.fragment_settings, container, false);
final TextView textView = root.findViewById(R.id.text_settings);
settingsViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
#Override
public void onChanged(#Nullable String s) {
textView.setText(s);
}
});
return root;
}
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
final Switch DarkMode = (Switch) getView().findViewById(R.id.DarkModeSwitch);
final boolean DarkModeVal = DarkMode.isChecked();
Log.d("Dark Mode Checked Value", String.valueOf(DarkModeVal));
DarkMode.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
callback.onCheckedChange(isChecked);
}
});
}
}
SettingsViewModel.java:
package com.barzalou.lpapineau.test.ui.settings;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
public class SettingsViewModel extends ViewModel {
private MutableLiveData<String> mText;
public SettingsViewModel() {
mText = new MutableLiveData<>();
mText.setValue("Settings");
}
public LiveData<String> getText() {
return mText;
}
}
CheckedChangeCallback.java:
package com.barzalou.lpapineau.test.ui;
public interface CheckedChangeCallback {
void onCheckedChange(boolean isChecked);
}
MainActivity.java:
package com.barzalou.lpapineau.test;
import android.content.Intent;
import android.content.SharedPreferences;
import android.media.audiofx.Equalizer;
import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.view.Menu;
import android.widget.CompoundButton;
import android.widget.Switch;
import com.barzalou.lpapineau.test.ui.CheckedChangeCallback;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.navigation.NavigationView;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
public class MainActivity extends AppCompatActivity implements CheckedChangeCallback {
private AppBarConfiguration mAppBarConfiguration;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
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) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
DrawerLayout drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
mAppBarConfiguration = new AppBarConfiguration.Builder(
R.id.nav_home, R.id.nav_gallery, R.id.nav_slideshow)
.setDrawerLayout(drawer)
.build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
NavigationUI.setupWithNavController(navigationView, navController);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onSupportNavigateUp() {
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
return NavigationUI.navigateUp(navController, mAppBarConfiguration)
|| super.onSupportNavigateUp();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_exit) {
finish();
System.exit(0);
}
return false;
}
public void onCheckedChange(boolean isChecked) {
Switch DarkMode = findViewById(R.id.DarkModeSwitch);
if (isChecked) {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
Log.d("Dark Mode Switch State", "On");
DarkMode.setChecked(true);
}
else {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
Log.d("Dark Mode Switch State", "Off");
DarkMode.setChecked(false);
}
}
}
fragment_settings.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/relativeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:background="#fff"
android:padding="10dp"
tools:context=".ui.home.HomeFragment">
<!-- Title -->
<TextView
android:id="#+id/text_settings"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:shadowColor="#bfbfbf"
android:shadowDx="5"
android:shadowDy="5"
android:shadowRadius="0.01"
android:text="#string/this_is_home"
android:textAlignment="center"
android:textColor="#000"
android:textSize="34sp" />
<!-- ...... -->
<!-- Card_View Settings -->
<androidx.cardview.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/card_view_outer"
android:layout_width="match_parent"
android:layout_height="90dp"
android:layout_gravity="center"
android:translationY="60dp"
android:layout_marginLeft="3dp"
android:layout_marginStart="3dp"
android:layout_marginTop="3dp"
card_view:cardBackgroundColor="#d3d3d3"
card_view:cardCornerRadius="4dp"
card_view:cardElevation="0dp" />
<androidx.cardview.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/card_view_inner"
android:layout_width="match_parent"
android:layout_height="90dp"
android:layout_gravity="center"
android:translationY="60dp"
android:layout_marginRight="3dp"
android:layout_marginEnd="3dp"
card_view:cardBackgroundColor="#f5f5f5"
card_view:cardCornerRadius="4dp"
card_view:cardElevation="3dp" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="10dp"
android:elevation="4dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:text="#string/Settings"
android:textSize="22sp"/>
<Switch
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:id="#+id/DarkModeSwitch"
android:text="#string/dark_mode"/>
</LinearLayout>
</androidx.cardview.widget.CardView>
<!-- .................. -->
<!-- Card_View 2 -->
<androidx.cardview.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/card_view_1"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_gravity="center"
android:translationY="170dp"
android:layout_marginRight="3dp"
android:layout_marginEnd="3dp"
card_view:cardBackgroundColor="#f5f5f5"
card_view:cardCornerRadius="4dp"
card_view:cardElevation="3dp" />
<androidx.cardview.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/card_view_2"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_gravity="center"
android:translationY="170dp"
android:layout_marginLeft="3dp"
android:layout_marginStart="3dp"
android:layout_marginTop="3dp"
card_view:cardBackgroundColor="#d3d3d3"
card_view:cardCornerRadius="4dp"
card_view:cardElevation="0dp" >
</androidx.cardview.widget.CardView>
<!-- ........... -->
</RelativeLayout>
How can this be fixed? I want it to stay flipped while the dark theme is on.
Thanks!
Because fragment recreated, the switch result is lost. So you should save the switch result. For example, SharedPreference.
Related
So it is exactly as the title suggests. I've created an app of which I will put the code beneath here, and when I call a fragment from the automaticly generated Home fragment which generates when you choose the template Navigation Drawer Activity, it pops up fine, and when I swipe back it dissapears again.
However, then when I press the button to call a fragment the second time, it just shows an empty screen.
MainActivity.java:
package eu.sleepy.emptyfragmentbug2;
import android.os.Bundle;
import android.view.View;
import android.view.Menu;
import android.widget.FrameLayout;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.navigation.NavigationView;
import androidx.fragment.app.FragmentManager;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
public class MainActivity extends AppCompatActivity {
private AppBarConfiguration mAppBarConfiguration;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
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) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
DrawerLayout drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
mAppBarConfiguration = new AppBarConfiguration.Builder(
R.id.nav_home, R.id.nav_gallery, R.id.nav_slideshow)
.setDrawerLayout(drawer)
.build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
NavigationUI.setupWithNavController(navigationView, navController);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onSupportNavigateUp() {
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
return NavigationUI.navigateUp(navController, mAppBarConfiguration)
|| super.onSupportNavigateUp();
}
#Override
public void onBackPressed(){
FragmentManager fm = getSupportFragmentManager();
if (fm.getBackStackEntryCount() > 0) {
System.out.println("popping backstack");
if (fm.getBackStackEntryAt(fm.getBackStackEntryCount() - 1).getName().equals("findThisFragment")) {
View linearLayout = findViewById(R.id.homefrag);
linearLayout.setVisibility(View.VISIBLE);
FrameLayout frameLayout = findViewById(R.id.blankfrag);
frameLayout.setVisibility(View.GONE);
}
} else {
System.out.println("nothing on backstack, calling super");
super.onBackPressed();
}
}
}
HomeFragment.java
package eu.sleepy.emptyfragmentbug2.ui.home;
import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import eu.sleepy.emptyfragmentbug2.BlankFragment;
import eu.sleepy.emptyfragmentbug2.R;
public class HomeFragment extends Fragment {
private HomeViewModel homeViewModel;
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
homeViewModel =
new ViewModelProvider(this).get(HomeViewModel.class);
View root = inflater.inflate(R.layout.fragment_home, container, false);
final TextView textView = root.findViewById(R.id.text_home);
homeViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
#Override
public void onChanged(#Nullable String s) {
textView.setText(s);
}
});
View.OnClickListener onClickListener = new View.OnClickListener() {
#Override
public void onClick(View view) {
BlankFragment nextFrag = new BlankFragment();
nextFrag.color = Color.LTGRAY; // This value is always different when the button is pressed, so calling the same fragment wouldn't work.
getParentFragment().getFragmentManager().beginTransaction()
.replace(((ViewGroup)getView().getParent()).getId(), nextFrag, "findThisFragment")
.addToBackStack("findThisFragment")
.commit();
View linearLayout = getActivity().findViewById(R.id.homefrag);
linearLayout.setVisibility(View.GONE);
}
};
Button button = root.findViewById(R.id.button);
button.setOnClickListener(onClickListener);
Button button2 = root.findViewById(R.id.button2);
button2.setOnClickListener(onClickListener);
return root;
}
}
It is commented in the code, but I'll say it here again nextFrag.color = Color.LTGRAY; is almost never the exact same color and thus is different every time, so defining the fragment once and calling the same fragment again when one button is called is not a viable option.
fragment_home.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/homefrag"
tools:context=".ui.home.HomeFragment">
<TextView
android:id="#+id/text_home"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:textAlignment="center"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="63dp"
android:layout_marginTop="155dp"
android:layout_marginEnd="89dp"
android:layout_marginBottom="153dp"
android:text="Button"
app:layout_constraintBottom_toTopOf="#+id/text_home"
app:layout_constraintEnd_toStartOf="#+id/button2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0" />
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="89dp"
android:layout_marginTop="158dp"
android:layout_marginEnd="73dp"
android:layout_marginBottom="150dp"
android:text="Button"
app:layout_constraintBottom_toTopOf="#+id/text_home"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/button"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
BlankFragment.java
package eu.sleepy.emptyfragmentbug2;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
public class BlankFragment extends Fragment {
public Integer color;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_blank, container, false);
FrameLayout frameLayout = root.findViewById(R.id.blankfrag);
frameLayout.setVisibility(View.VISIBLE);
// Inflate the layout for this fragment
return root;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
System.out.println("But it does output");
CreateImage();
}
public void CreateImage() {
FrameLayout frameLayout = getActivity().findViewById(R.id.blankfrag);
frameLayout.setVisibility(View.VISIBLE);
ImageView imageView = new ImageView(getContext());
imageView.setBackgroundColor(color);
LinearLayout.LayoutParams layoutParams1 = new LinearLayout.LayoutParams(300, 500);
layoutParams1.setMargins(25, 0, 0,0);
imageView.setLayoutParams(layoutParams1);
frameLayout.addView(imageView);
}
}
fragment_blank.xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/blankfrag"
tools:context=".BlankFragment">
</FrameLayout>
If there is a need for more files, please let me know.
It still executes the code in the called fragment, because it still outputs the System.out.println("But it does output"); in the console as But it does output.
Yet, it doesn't display the fragment when the button is pressed for a second time.
Any help would be really appreciated.
I forgot the fm.popBackStackImmediate(); in the onBackPressed() method in the MainActivity.java. Which, when actually placed in onBackPressed() made everything work perfectly.
all. I'm having a problem.
I am trying to make an application, wherein a navigation-drawer is the source of navigation. In this application, I have some fragments with activities. The problem is, that if I run my profile fragment (which have uses tablayout and recyclerview) in an application for itself, it works. The application when it runs in it's own application.
However, when I attempt to add it to an application, wherein it should be a fragment in a navigation drawer, the application can compile, but when I click on the menuitem in the emulator, it crashes.
I will add the code I have at the moment:
Main Activity
import android.view.MenuItem;
import android.view.View;
import android.view.Menu;
import android.content.Intent;
import com.example.sustainably.ui.myprofile.MainActivityProfile;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.navigation.NavigationView;
import androidx.annotation.NonNull;
import androidx.core.view.GravityCompat;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
public class MainActivity extends AppCompatActivity {
private AppBarConfiguration mAppBarConfiguration;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
mAppBarConfiguration = new AppBarConfiguration.Builder(
R.id.nav_home, R.id.nav_friends, R.id.nav_messages, R.id.nav_bookmarks, R.id.nav_myprofile, R.id.nav_discoverforums, R.id.nav_settings, R.id.nav_logout)
.setDrawerLayout(drawer)
.build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
NavigationUI.setupWithNavController(navigationView, navController);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onSupportNavigateUp() {
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
return NavigationUI.navigateUp(navController, mAppBarConfiguration)
|| super.onSupportNavigateUp();
}
public boolean onNavigationItemSelected(MenuItem item) {
NavigationView navigationView = (NavigationView)findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
int id = menuItem.getItemId();
switch (menuItem.getItemId()) {
case R.id.nav_home:
// code here
break;
case R.id.nav_friends:
// code here
break;
case R.id.nav_messages:
// code here
break;
case R.id.nav_bookmarks:
// code here
break;
case R.id.nav_myprofile:
Intent intent=new Intent(MainActivity.this, MainActivityProfile.class);
startActivity(intent);
break;
case R.id.nav_discoverforums:
//code here
break;
case R.id.nav_settings:
//code here
break;
case R.id.nav_logout:
//code here
break;
}
DrawerLayout drawer = (DrawerLayout)findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
});
return false;
}
}
and in the profile fragment package i have 6 java classes:
BookmarkModel.java
private String Title;
private int Photo;
public BookmarkModel() {
}
public BookmarkModel(String title, int photo) {
Title = title;
Photo = photo;
}
// Getter
public String getTitle() {
return Title;
}
public int getPhoto() {
return Photo;
}
// Setter
public void setTitle(String title) {
Title = title;
}
public void setPhoto(int photo) {
Photo = photo;
}
}
MainActivityProfile.java
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager.widget.ViewPager;
import androidx.viewpager2.widget.ViewPager2;
import android.os.Bundle;
import com.example.sustainably.R;
import com.google.android.material.tabs.TabLayout;
public class MainActivityProfile extends AppCompatActivity {
private TabLayout tabLayout;
private ViewPager viewPager;
private ViewPagerAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_myprofile);
tabLayout = (TabLayout) findViewById(R.id.tablayout_id);
viewPager = (ViewPager) findViewById(R.id.viewpager_id);
adapter = new ViewPagerAdapter(getSupportFragmentManager());
// Add Fragment Here
adapter.AddFragment(new PublicBookmarkFragment(), "Public Bookmarks");
adapter.AddFragment(new LatestPostsFragment(), "Latest Posts");
viewPager.setAdapter(adapter);
tabLayout.setupWithViewPager(viewPager);
tabLayout.getTabAt(0).setIcon(R.drawable.ic_outline_bookmarks_24);
tabLayout.getTabAt(1).setIcon(R.drawable.ic_outline_textsms_24);
}
}
PublicBookmarkFragment
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.example.sustainably.R;
import java.util.ArrayList;
import java.util.List;
public class PublicBookmarkFragment extends Fragment {
View v;
private RecyclerView myrecyclerview;
private List<BookmarkModel> lstBookmarkModel;
public PublicBookmarkFragment() {
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
v = inflater.inflate(R.layout.public_bookmarks_fragment, container, false);
myrecyclerview = (RecyclerView) v.findViewById(R.id.bookmarks_recyclerview);
RecyclerViewAdapter recyclerAdapter = new RecyclerViewAdapter(getContext(), lstBookmarkModel);
myrecyclerview.setLayoutManager(new GridLayoutManager(getContext(), 2));
myrecyclerview.setAdapter(recyclerAdapter);
return v;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
lstBookmarkModel = new ArrayList<>();
lstBookmarkModel.add(new BookmarkModel("Salad", R.drawable.annapelzer));
lstBookmarkModel.add(new BookmarkModel("Pasta", R.drawable.brookelark_1));
lstBookmarkModel.add(new BookmarkModel("Fruit Salad", R.drawable.brookelark_2));
lstBookmarkModel.add(new BookmarkModel("Smoothies with fruit", R.drawable.brookelark_3));
lstBookmarkModel.add(new BookmarkModel("Soup", R.drawable.cala));
lstBookmarkModel.add(new BookmarkModel("Lobster Salad", R.drawable.davide_cantelli));
lstBookmarkModel.add(new BookmarkModel("Breakfast Toast with Berries", R.drawable.joseph_gonzales));
}
}
RecyclerViewAdapter
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.sustainably.R;
import java.util.List;
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder> {
Context mContext;
List<BookmarkModel> mData;
public RecyclerViewAdapter(Context mContext, List<BookmarkModel> mData) {
this.mContext = mContext;
this.mData = mData;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v;
v = LayoutInflater.from(mContext).inflate(R.layout.item_bookmarks, parent, false);
MyViewHolder vHolder = new MyViewHolder(v);
return vHolder;
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
holder.tv_title.setText(mData.get(position).getTitle());
holder.img.setImageResource(mData.get(position).getPhoto());
}
#Override
public int getItemCount() {
return mData.size();
}
public static class MyViewHolder extends RecyclerView.ViewHolder {
private TextView tv_title;
private ImageView img;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
tv_title = (TextView) itemView.findViewById(R.id.title_bookmarks);
img = (ImageView) itemView.findViewById(R.id.img_bookmarks);
}
}
}
ViewPagerAdapter
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
public class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> lstFragment = new ArrayList<>();
private final List<String> lstTitles = new ArrayList<>();
public ViewPagerAdapter(#NonNull FragmentManager fm) {
super(fm);
}
#NonNull
#Override
public Fragment getItem(int position) {
return lstFragment.get(position);
}
#Override
public int getCount() {
return lstTitles.size();
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
return lstTitles.get(position);
}
public void AddFragment (Fragment fragment, String title) {
lstFragment.add(fragment);
lstTitles.add(title);
}
}
fragment_myprofile.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/myprofile"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<include
layout="#layout/profile_header"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:id="#+id/TabContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.tabs.TabLayout
android:id="#+id/tablayout_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabGravity="fill"
app:tabIconTint="#color/dark_green"
app:tabIndicatorColor="#color/dark_green"
app:tabInlineLabel="true"
app:tabMode="fixed"
app:tabRippleColor="#color/light_green"
app:tabSelectedTextColor="#color/dark_green"
app:tabTextAppearance="#style/TextAppearance.AppCompat.Small"></com.google.android.material.tabs.TabLayout>
<androidx.viewpager.widget.ViewPager
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/viewpager_id"></androidx.viewpager.widget.ViewPager>
</LinearLayout>
</LinearLayout>
public_bookmarks_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/bookmarks_recyclerview">
</androidx.recyclerview.widget.RecyclerView>
</LinearLayout>
item_bookmarks.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardUseCompatPadding="true"
app:cardCornerRadius="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="#+id/img_bookmarks"
android:layout_width="200dp"
android:layout_height="200dp"
android:src="#mipmap/ic_launcher"
android:scaleType="centerCrop" />
<TextView
android:id="#+id/title_bookmarks"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="#color/dark_green"
android:padding="5dp"
android:text="#string/title"
android:textSize="16sp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
I'm new at asking questions in here, so if I missed some information you need, or messed something up, please tell me what you need, and I will provide that aswell. Hope you can help.
For clarification as requested:
Logcat errormessages when I click on the menu
2021-05-06 15:28:54.971 18053-18053/com.example.sustainably E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.sustainably, PID: 18053
java.lang.ClassCastException: com.example.sustainably.ui.myprofile.MainActivityProfile cannot be cast to androidx.fragment.app.Fragment
at androidx.fragment.app.Fragment.instantiate(Fragment.java:548)
at androidx.fragment.app.FragmentContainer.instantiate(FragmentContainer.java:57)
at androidx.fragment.app.FragmentManager$3.instantiate(FragmentManager.java:390)
at androidx.navigation.fragment.FragmentNavigator.instantiateFragment(FragmentNavigator.java:132)
at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.java:162)
at androidx.navigation.fragment.FragmentNavigator.navigate(FragmentNavigator.java:58)
at androidx.navigation.NavController.navigate(NavController.java:1066)
at androidx.navigation.NavController.navigate(NavController.java:944)
at androidx.navigation.NavController.navigate(NavController.java:877)
at androidx.navigation.ui.NavigationUI.onNavDestinationSelected(NavigationUI.java:97)
at androidx.navigation.ui.NavigationUI$3.onNavigationItemSelected(NavigationUI.java:453)
at com.google.android.material.navigation.NavigationView$1.onMenuItemSelected(NavigationView.java:217)
at androidx.appcompat.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:834)
at androidx.appcompat.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:158)
at androidx.appcompat.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:985)
at com.google.android.material.internal.NavigationMenuPresenter$1.onClick(NavigationMenuPresenter.java:416)
at android.view.View.performClick(View.java:7448)
at android.view.View.performClickInternal(View.java:7425)
at android.view.View.access$3600(View.java:810)
at android.view.View$PerformClick.run(View.java:28305)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
mobile_navigation.xml
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/mobile_navigation"
app:startDestination="#+id/nav_home">
<fragment
android:id="#+id/nav_home"
android:name="com.example.sustainably.ui.home.HomeFragment"
android:label="#string/menu_home"
tools:layout="#layout/fragment_home" />
<fragment
android:id="#+id/nav_friends"
android:name="com.example.sustainably.ui.friends.FriendsFragment"
android:label="#string/menu_friends"
tools:layout="#layout/fragment_friends" />
<fragment
android:id="#+id/nav_bookmarks"
android:name="com.example.sustainably.ui.bookmarks.BookmarksFragment"
android:label="#string/menu_bookmarks"
tools:layout="#layout/fragment_bookmarks" />
<fragment
android:id="#+id/nav_myprofile"
android:name="com.example.sustainably.ui.myprofile.profileRecycle.MyProfileFragment"
android:label="#string/menu_myprofile"
tools:layout="#layout/fragment_myprofile" />
<fragment
android:id="#+id/nav_discoverforums"
android:name="com.example.sustainably.ui.discoverforums.DiscoverForumsFragment"
android:label="#string/menu_discoverforums"
tools:layout="#layout/fragment_discoverforums" />
<fragment
android:id="#+id/nav_messages"
android:name="com.example.sustainably.ui.messages.MessagesFragment"
android:label="#string/menu_messages"
tools:layout="#layout/fragment_messages" />
</navigation>
The code in it's entirety: https://github.com/CabCabz/SustainablyProblem.git
suggestion:
I analyzed your code, you should not used default navigation drawer setup with mobile_navigation.xml.
Setup drawer menu without mobile_navigation.xml: https://stackoverflow.com/a/67389269/12660050
Solution:
1) As you are using default drawer with mobile_navigation.xml you do not need to
use onNavigationItemSelected() method. So, before doing anything remove it from
your Main Activity.
2) Go to the mobile_navigation.xml file and change tag name fragment to activity in which you are using as a MainActivityProfile.java.
Before:
<fragment
android:id="#+id/nav_myprofile"
android:name="com.example.sustainably.ui.myprofile.profileRecycle.MyProfileFragment"
android:label="#string/menu_myprofile"
tools:layout="#layout/fragment_myprofile" />
After:
<activity
android:id="#+id/nav_myprofile"
android:name="com.example.sustainably.ui.myprofile.profileRecycle.MyProfileFragment"
android:label="#string/menu_myprofile"
tools:layout="#layout/fragment_myprofile" />
By changing only this you can solve your problem!!
I am trying to learn coding in Android Studio but I am having trouble with the activities.
I have a google map code that I was to add to the navigation drawer but I can't because the error always says MapsActivity cannot be cast to androidx.fragment.app.Fragment
here is my MapActivity.Java
package ***.***.***.ui.map;
import androidx.fragment.app.FragmentActivity;
import android.annotation.SuppressLint;
import android.content.Context;
import android.location.Address;
import android.location.Geocoder;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.WindowManager;
import android.widget.TextView;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import java.io.IOException;
import java.util.List;
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private Object LocationServices;
GoogleMap mMap;
private GoogleMap.OnCameraIdleListener onCameraIdleListener;
private TextView resutText;
#Override
public void onResume() {
super.onResume();
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(***.***.***.R.id.map);
mapFragment.getMapAsync(this);
resutText = (TextView) findViewById(***.***.***.R.id.dragg_result);
configureCameraIdle();
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.setOnCameraIdleListener(onCameraIdleListener);
googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
String locationProvider = LocationManager.NETWORK_PROVIDER;
#SuppressLint("MissingPermission") android.location.Location lastKnownLocation = locationManager.getLastKnownLocation(locationProvider);
double userLat = lastKnownLocation.getLatitude();
double userLong = lastKnownLocation.getLongitude();
LatLng user = new LatLng(userLat, userLong);
googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(userLat, userLong), 16.0f));
}
private void configureCameraIdle() {
onCameraIdleListener = new GoogleMap.OnCameraIdleListener() {
#Override
public void onCameraIdle() {
LatLng latLng = mMap.getCameraPosition().target;
Geocoder geocoder = new Geocoder(MapsActivity.this);
try {
List<Address> addressList = geocoder.getFromLocation(latLng.latitude, latLng.longitude, 1);
if (addressList != null && addressList.size() > 0) {
String locality = addressList.get(0).getAddressLine(0);
String country = addressList.get(0).getCountryName();
if (!locality.isEmpty() && !country.isEmpty())
resutText.setText(locality + " " + country);
}
} catch (IOException e) {
e.printStackTrace();
}
}
};
}
protected void setStatusBarTranslucent(boolean makeTranslucent) {
if (makeTranslucent) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
} else {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
}
}
and the activity_maps.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<fragment
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MapsActivity" />
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:layout_marginStart="172dp"
android:layout_marginTop="310dp"
android:layout_marginEnd="172dp"
android:layout_marginBottom="356dp"
android:adjustViewBounds="true"
android:maxWidth="65dp"
android:maxHeight="65dp"
android:src="#drawable/car_pin" />
<!-- Implementation of find my location button -->
<TextView
android:id="#+id/dragg_result"
android:layout_width="260dp"
android:layout_height="84dp"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:layout_marginStart="75dp"
android:layout_marginTop="74dp"
android:layout_marginEnd="75dp"
android:layout_marginBottom="572dp"
android:text="TextView" />
<fragment
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/mobile_navigation" />
</RelativeLayout>
Also the MainActivity.java
package ***.***.***;
import android.os.Bundle;
import android.view.View;
import android.view.Menu;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.navigation.NavigationView;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
public class MainActivity extends AppCompatActivity {
private AppBarConfiguration mAppBarConfiguration;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
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) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
DrawerLayout drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
mAppBarConfiguration = new AppBarConfiguration.Builder(
R.id.nav_home, R.id.nav_gallery, R.id.nav_slideshow)
.setDrawerLayout(drawer)
.build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
NavigationUI.setupWithNavController(navigationView, navController);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onSupportNavigateUp() {
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
return NavigationUI.navigateUp(navController, mAppBarConfiguration)
|| super.onSupportNavigateUp();
}
}
What can I do to make it work without redoing all of the code, thanks in advance.
I am not quite sure, but I think you have to put your <framgent> inside a <FramgeLayout> in your xml file like this:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="#+id/mapfragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.MapFragment"/>
<!-- other components -->
<fragment
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/mobile_navigation" />
</FrameLayout>
it is possible that your imports are wrong. Does it work if you import this in your java class android.support.v4.app.FragmentActivity instead of androidx.fragment.app.FragmentActivity? I think the error is in the imports than
I am trying to open my NavigationDrawer which I created in my MainActivity in my HomeFragment by clicking on an Icon. When I click on the Icon I want the drawer to open... Can this be done even though, I have it in my MainActivity file and NOT my HomeFragment?
Below you have my fragment_home.xml file and HomeFragment.java
MainActivity.java
package com.e.events;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.Fragment;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.MenuItem;
import com.e.events.Fragment.HomeFragment;
import com.e.events.Fragment.NotificationsFragment;
import com.e.events.Fragment.ProfileFragment;
import com.e.events.Fragment.SaveFragment;
import com.e.events.Fragment.SearchFragment;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.navigation.NavigationView;
import com.google.firebase.auth.FirebaseAuth;
public class MainActivity extends AppCompatActivity implements DrawerLocker, NavigationView.OnNavigationItemSelectedListener {
private DrawerLayout drawer;
BottomNavigationView bottomNavigationView;
Fragment selectedFragment = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar,
R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
bottomNavigationView = findViewById(R.id.bottom_navigation);
bottomNavigationView.setOnNavigationItemSelectedListener(navigationItemSelectedListener);
Bundle intent = getIntent().getExtras();
if (intent != null) {
String publisher = intent.getString("publisherid");
SharedPreferences.Editor editor = getSharedPreferences("PREFS", MODE_PRIVATE).edit();
editor.putString("profileid", publisher);
editor.apply();
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
new ProfileFragment()).commit();
} else {
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
new HomeFragment()).commit();
}
}
#Override
public void onBackPressed() {
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
int id = menuItem.getItemId();
switch (id) {
case R.id.nav_edit_profile:
Intent editProfile = new Intent(MainActivity.this, EditProfileActivity.class);
startActivity(editProfile);
break;
case R.id.nav_settings:
Intent settings = new Intent(MainActivity.this, SettingsActivity.class);
startActivity(settings);
break;
case R.id.nav_logout:
Intent logout = new Intent(MainActivity.this, StartActivity.class);
FirebaseAuth.getInstance().signOut();
startActivity(new Intent(MainActivity.this, StartActivity.class)
.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
break;
}
drawer.closeDrawer(GravityCompat.START);
return true;
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
int id = item.getItemId();
if (id == R.id.nav_edit_profile) {
return true;
}
return super.onOptionsItemSelected(item);
}
private BottomNavigationView.OnNavigationItemSelectedListener navigationItemSelectedListener =
new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.nav_home:
selectedFragment = new HomeFragment();
break;
case R.id.nav_search:
selectedFragment = new SearchFragment();
break;
case R.id.nav_notifications:
selectedFragment = new NotificationsFragment();
break;
case R.id.nav_profile:
SharedPreferences.Editor editor = getSharedPreferences("PREFS", MODE_PRIVATE).edit();
editor.putString("profileid", FirebaseAuth.getInstance().getCurrentUser().getUid());
editor.apply();
selectedFragment = new ProfileFragment();
break;
case R.id.nav_save:
selectedFragment = new SaveFragment();
break;
}
if (selectedFragment != null) {
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
selectedFragment).commit();
}
return true;
}
};
public void setDrawerLocked(boolean enabled){
if(enabled){
drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
}else{
drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
}
}
}
fragment_home.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".Fragment.HomeFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/windowBackground">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar_home_fragment"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?android:attr/windowBackground"
android:elevation="4dp"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/events_logo_main_activity"
android:layout_width="180dp"
android:layout_height="45dp"
android:layout_centerInParent="true"
android:layout_marginTop="10dp"
android:src="#drawable/events_logo_black_max_size" />
<ImageView
android:id="#+id/camera_create_an_event_main_activity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerInParent="true"
android:layout_marginEnd="11dp"
android:src="#drawable/ic_camera_create_events_home_fragment_black" />
<ImageView
android:id="#+id/three_bars_settings_main_activity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerInParent="true"
android:src="#drawable/ic_three_bars_settings_home_fragment_black" />
</RelativeLayout>
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/bar">
</androidx.recyclerview.widget.RecyclerView>
</LinearLayout>
<ProgressBar
android:id="#+id/progress_circular"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
</RelativeLayout>
HomeFragment
package com.e.events.Fragment;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.widget.Toolbar;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.e.events.Adapter.PostAdapter;
import com.e.events.EditProfileActivity;
import com.e.events.MainActivity;
import com.e.events.Model.Post;
import com.e.events.OptionsActivity;
import com.e.events.PostActivity;
import com.e.events.R;
import com.google.android.material.navigation.NavigationView;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.List;
public class HomeFragment extends Fragment {
ImageView options;
DrawerLayout drawer;
ProgressBar progressBar;
private RecyclerView recyclerView;
private PostAdapter postAdapter;
private List<Post> postLists;
private ImageView camera_create_event;
private List<String> followingList;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_home, container, false);
recyclerView = view.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
linearLayoutManager.setReverseLayout(true);
linearLayoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(linearLayoutManager);
postLists = new ArrayList<>();
postAdapter = new PostAdapter(getContext(), postLists);
recyclerView.setAdapter(postAdapter);
progressBar = view.findViewById(R.id.progress_circular);
drawer = view.findViewById(R.id.nav_view);
Toolbar toolbar = view.findViewById(R.id.toolbar_home_fragment);
options = view.findViewById(R.id.three_bars_settings_main_activity);
options.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
drawer.openDrawer(GravityCompat.START);
}
});
camera_create_event = view.findViewById(R.id.camera_create_an_event_main_activity);
camera_create_event.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), PostActivity.class);
startActivity(intent);
}
});
checkFollowing();
return view;
}
private void checkFollowing() {
followingList = new ArrayList<>();
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Follow")
.child(FirebaseAuth.getInstance().getCurrentUser().getUid())
.child("following");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
followingList.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
followingList.add(snapshot.getKey());
}
readPosts();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
private void readPosts() {
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Posts");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
postLists.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
Post post = snapshot.getValue(Post.class);
for (String id : followingList) {
if (post.getPublisher().equals(id)) {
postLists.add(post);
}
}
}
postAdapter.notifyDataSetChanged();
progressBar.setVisibility(View.GONE);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
Logcat
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.e.events, PID: 18229
java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.drawerlayout.widget.DrawerLayout.openDrawer(int)' on a null object reference
at com.e.events.Fragment.HomeFragment$1.onClick(HomeFragment.java:85)
at android.view.View.performClick(View.java:6663)
at android.view.View.performClickInternal(View.java:6635)
at android.view.View.access$3100(View.java:794)
at android.view.View$PerformClick.run(View.java:26199)
at android.os.Handler.handleCallback(Handler.java:907)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:216)
at android.app.ActivityThread.main(ActivityThread.java:7625)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)
you don't have any DrawerLayout in your fragment_home.xml try to change your RelativeLayout to DrawerLayout :
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start"
tools:context=".Fragment.HomeFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/windowBackground">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar_home_fragment"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?android:attr/windowBackground"
android:elevation="4dp"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/events_logo_main_activity"
android:layout_width="180dp"
android:layout_height="45dp"
android:layout_centerInParent="true"
android:layout_marginTop="10dp"
android:src="#drawable/events_logo_black_max_size" />
<ImageView
android:id="#+id/camera_create_an_event_main_activity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerInParent="true"
android:layout_marginEnd="11dp"
android:src="#drawable/ic_camera_create_events_home_fragment_black" />
<ImageView
android:id="#+id/three_bars_settings_main_activity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerInParent="true"
android:src="#drawable/ic_three_bars_settings_home_fragment_black" />
</RelativeLayout>
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/bar">
</androidx.recyclerview.widget.RecyclerView>
</LinearLayout>
<ProgressBar
android:id="#+id/progress_circular"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
</androidx.drawerlayout.widget.DrawerLayout>
if you want to open drawer layout of your activity from your fragment then add this code in your fragment:
Activity mActivity;
#Override
public void onAttach(#NonNull Context context) {
super.onAttach(context);
if (context instanceof Activity) {
mActivity = (Activity) context;
}
}
get your drawer layout in your fragment as:
DrawerLayout drawer = mActivity.findViewById(R.id.drawer_layout);
now you can open or close your drawer layout from your activity
yourImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//open or close your drawer according to your need
}
});
I have an app with a bottom navigation view that changes between 4 fragments and I'm trying to make it so that those fragments are displayed with data from firebase using FirebaseRecyclerView Adapter.
I have everything set up but the layout that the FirebaseRecyclerView Adapter inflates is not appearing.
My MainAcitivity.java
package com.pap.diogo.pilltrack;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomNavigationView;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import com.firebase.ui.database.SnapshotParser;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;
public class MainActivity extends AppCompatActivity {
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Fragment selectedFragment = null;
switch (item.getItemId()) {
case R.id.navigation_home:
selectedFragment = new HomeFragment();
break;
case R.id.navigation_pills:
selectedFragment = new PillsFragment();
break;
case R.id.navigation_appointment:
selectedFragment = new AppointsFragment();
break;
case R.id.navigation_account:
selectedFragment = new AccountFragment();
break;
}
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, selectedFragment).commit();
return true;
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user == null) {
Intent VerifyLogin = new Intent(MainActivity.this, Launcher.class);
VerifyLogin.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(VerifyLogin);
}
BottomNavigationView navigation = findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new HomeFragment()).commit();
}
#Override
protected void onStart() {
super.onStart();
}
#Override
protected void onStop() {
super.onStop();
}
};
My AccountFragment.java
package com.pap.diogo.pilltrack;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import com.firebase.ui.database.SnapshotParser;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;
import com.google.firebase.database.ValueEventListener;
public class AccountFragment extends Fragment {
private RecyclerView AccountUsers;
private View mMainView;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
mMainView = inflater.inflate(R.layout.fragment_account, container, false);
AccountUsers = mMainView.findViewById(R.id.accountlist);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
AccountUsers.setLayoutManager(linearLayoutManager);
AccountUsers.setHasFixedSize(true);
return mMainView;
}
#Override
public void onStart() {
super.onStart();
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
final String userid = user.getUid();
final DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Users");
FirebaseRecyclerOptions<Account> AccountQ = new FirebaseRecyclerOptions.Builder<Account>().setQuery(ref, Account.class).setLifecycleOwner(this).build();
FirebaseRecyclerAdapter<Account, AccountInfo> AccountAdapter = new FirebaseRecyclerAdapter<Account, AccountInfo>(AccountQ){
#NonNull
#Override
public AccountInfo onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
return new AccountInfo(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.account, viewGroup, false));
}
#Override
protected void onBindViewHolder(#NonNull final AccountInfo holder, int position, #NonNull final Account model) {
ref.child(userid).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
final String name = dataSnapshot.child("name").getValue().toString();
final String age = dataSnapshot.child("idade").getValue().toString();
holder.setName(name);
holder.setAge(age);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
};
AccountUsers.setAdapter(AccountAdapter);
}
public static class AccountInfo extends RecyclerView.ViewHolder{
View AccountL;
public AccountInfo(#NonNull View itemView) {
super(itemView);
AccountL = itemView;
}
public void setName(String name){
TextView AccountName = AccountL.findViewById(R.id.AccountName0);
AccountName.setText(name);
}
public void setAge(String age){
TextView AccountAge = AccountL.findViewById(R.id.AccountAge0);
AccountAge.setText(age);
}
}
}
My account.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="#+id/AccountUser"
android:layout_width="match_parent"
android:layout_height="163dp"
android:layout_marginStart="15dp"
android:layout_marginLeft="15dp"
android:layout_marginTop="15dp"
android:layout_marginEnd="15dp"
android:layout_marginRight="15dp"
android:layout_marginBottom="15dp"
android:background="#drawable/edit_bg"
android:padding="15dp">
<RelativeLayout
android:id="#+id/AccountImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_user"/>
</RelativeLayout>
<RelativeLayout
android:id="#+id/AccountInfos"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/AccountImage"
android:layout_toEndOf="#id/AccountImage"
android:layout_marginStart="15dp"
android:layout_marginLeft="15dp">
<TextView
android:id="#+id/AccountName0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:text="Nome1"
android:textColor="#color/colorWhite"
android:textSize="20sp"
android:textStyle="bold" />
<TextView
android:id="#+id/AccountAge0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/AccountName0"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:text="Idade1"
android:textColor="#color/colorWhite"
android:textSize="20sp"
android:textStyle="bold" />
<Button
android:id="#+id/AccountChangePass"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/AccountAge0"
android:text="Mudar Palavra-Passe"
android:textColor="#color/colorWhite"
android:textSize="18sp"
android:textStyle="bold"
android:textAllCaps="false"
android:padding="10dp"
android:layout_marginTop="10dp"
android:background="#drawable/custom_button"/>
</RelativeLayout>
</RelativeLayout>
<RelativeLayout
android:id="#+id/add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/AccountUser">
<ImageButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_marginLeft="15dp"
android:layout_marginEnd="15dp"
android:layout_marginRight="15dp"
android:src="#drawable/ic_add"
android:padding="5dp"
android:background="#drawable/add_button"/>
</RelativeLayout>
</RelativeLayout>
My fragment_account.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/accountlist">
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
GitHub of my APP
I fixed it.
All I had to do was to remove this line of code:
AccountUsers.setHasFixedSize(true);