Android / Java | Navigation Drawer's TextView .setText not working through SharedPreferences - java

I have a Fragment that allows the user to change their username that will be displayed in a TextView inside a Navigation Drawer. The Fragment, 'SettingsFragment' is inflated in the MainActivity.
SettingsFragment has an EditText where the user enters their username and a button to apply changes. The Navigation Drawer was created in the MainActivity, so I setup SharedPreferences to send the username over to MainActivity. I then proceeded to change the TextView in the Navigation Drawer with .setText(username), however nothing happens. But when I relaunch the app, the Navigation Drawer's TextView changes to the actual username that the user entered in the EditText.
SettingsFragment.java:
public class SettingsFragment extends Fragment {
public SettingsFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_settings, container, false);
final TextInputEditText teiUserName = view.findViewById(R.id.teiUserName);
final TextView tvEditTextSub = view.findViewById(R.id.tvEditTextSubstitute);
Button btnApplyChanges = view.findViewById(R.id.btnApplyChanges);
btnApplyChanges.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final String user_name = String.valueOf(teiUserName.getText());
tvEditTextSub.setText(user_name);
SharedPreferences.Editor editor = getActivity().getSharedPreferences("myPrefs", MODE_PRIVATE).edit();
editor.putString("name", user_name);
editor.apply();
}
});
return view;
}}
SettingsFragment XML:
<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:padding="10dp"
tools:context="com.miguelpeachey.marketplacesimulator.Fragments.SettingsFragment">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.TextInputEditText
android:id="#+id/teiUserName"
android:layout_width="248dp"
android:layout_height="wrap_content"
android:layout_above="#+id/btnApplyChanges"
android:layout_marginBottom="28dp"
android:text="User"
android:textColorHint="#000" />
<Button
android:id="#+id/btnApplyChanges"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="28dp"
android:background="#33993f"
android:padding="12dp"
android:text="Apply Changes"
android:textColor="#FFF" />
</RelativeLayout>
MainActivity.java:
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
Fragment fragment;
SharedPreferences sharedPreferences;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
DrawerLayout drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
View headerView = navigationView.getHeaderView(0);
final TextView tvDrawerUsername = headerView.findViewById(R.id.tvDrawerUsername);
setSupportActionBar(toolbar);
sharedPreferences = getSharedPreferences("myPrefs", Context.MODE_PRIVATE);
final String usernameID = sharedPreferences.getString("name", "User");
if (drawer.isDrawerOpen(GravityCompat.START)) {
tvDrawerUsername.setText(usernameID);
}}
There is more code in MainActivity.java but there's no need in including it.
In MainActivity.java, I also tried:
if (drawer.isDrawerOpen(GravityCompat.START)) {
tvDrawerUsername.setText(usernameID);
}
But it didn't even change the Navigation Drawer's TextView (tvDrawerUsername) after relaunching the app.
In conclusion, the app won't update tvDrawerUsername straight after the button click, but only after I relaunch the app.

Try This one:
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
Fragment fragment;
SharedPreferences sharedPreferences;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sharedPreferences = getSharedPreferences("myPrefs", Context.MODE_PRIVATE);Toolbar toolbar = findViewById(R.id.toolbar);
DrawerLayout drawer = findViewById(R.id.drawer_layout);
NavigationView navigationView = findViewById(R.id.nav_view);
View headerView = navigationView.getHeaderView(0);
final TextView tvDrawerUsername = headerView.findViewById(R.id.tvDrawerUsername);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, null, "navigation_drawer_open", "navigation_drawer_close") {
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
// Do whatever you want here
}
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
final String usernameID = sharedPreferences.getString("name", "User");
tvDrawerUsername.setText(usernameID);
}
};
drawer.addDrawerListener(toggle);
toggle.syncState();
setSupportActionBar(toolbar);
}

Try defining an TextView attribute on your SettingsFragment class definition :
public class SettingsFragment extends Fragment {
TextView tv;
public SettingsFragment() {
// Required empty public constructor
}
Define an setter for this attribute on the same class :
public void setTextView(TextView tv){
this.tv = tv
}
And from your activity, after initializing your fragment and your textView , pass the textView via the setter you just created :
fragment = new SettingsFragment();
fragment.setTextView(tvDrawerUsername);
Finally add textView.setText(user_name); iniside you onlick() method :
btnApplyChanges.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final String user_name = String.valueOf(teiUserName.getText());
tvEditTextSub.setText(user_name);
SharedPreferences.Editor editor = getActivity().getSharedPreferences("myPrefs", MODE_PRIVATE).edit();
editor.putString("name", user_name);
editor.apply();
textView.setText(user_name);
}
});
Hope this helps

Related

Can't see top toolbar even after calling setSupportActionBar

I'm trying to add a top toolbar, with an options menu in it, in a fragment. Upon running it on the emulator the toolbar doesn't show up.
I have called setSupportActionBar(toolbar), still not sure what's wrong.
EDIT: I've already changed the app theme to NoActionBar.
ProfileFragment.java
public class ProfileFragment extends Fragment {
private static final String TAG = "ProfileFragment";
private static final int ACTIVITY_NUM = 4;
private Toolbar toolbar;
private BottomNavigationViewEx bottomNavigationView;
private Context mContext;
//firebase
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_profile, container, false);
toolbar = view.findViewById(R.id.profiletoolbar);
bottomNavigationView = view.findViewById(R.id.bottomnav);
mContext = getActivity();
Log.d(TAG, "onCreateView: started.");
setupBottomNavigationView();
setupToolBar();
return view;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
setHasOptionsMenu(true);
super.onCreate(savedInstanceState);
}
//bottom nav setup
public void setupBottomNavigationView() {
Log.d(TAG, "setupBottomNavigationView: starting bottomnavsetup");
BottomNavigationViewHelper.setupBottomNavigationView(bottomNavigationView);
BottomNavigationViewHelper.enableBottomNav(mContext, bottomNavigationView);
Menu menu = bottomNavigationView.getMenu();
MenuItem menuItem = menu.getItem(ACTIVITY_NUM);
menuItem.setChecked(true);
}
//toolbar setup
private void setupToolBar() {
((AppCompatActivity)getActivity()).setSupportActionBar(toolbar);
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
if (item.getItemId() == R.id.signout) {
Toast.makeText(mContext, "Sign out clicked", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onOptionsItemSelected: attempting to sign out");
mAuth.signOut();
getActivity().finish();
}
return super.onOptionsItemSelected(item);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) {
menuInflater.inflate(R.menu.profile_menu, menu);
super.onCreateOptionsMenu(menu, menuInflater);
}
}
snippet_top_profile_bar.xml (This is the toolbar)
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#drawable/white_grey_border_bottom">
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/profiletoolbar">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:text="#username"
android:id="#+id/username"/>
</RelativeLayout>
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
I have all the necessary imports.
This method will work in Activity. But, here you are trying to do it with Fragment. fragments are sub activities so they have limited scope to do things.
Another thing that may happen, You should change the Activity theme to noActionbar.
By using this, default toolbar will be hide your custom toolbar will be displayed.

Can't Change Toolbar Color From Different Class

I am trying to change toolbar color from different class, but always failed. I don't know, what's wrong?
I've tried to do this using LayoutInflater but still failed. Can you help me to solve this issue?
LoadColor.java
public class LoadColor {
private Context context;
private HomeActivity hA;
final String KEY_SAVED_RADIO_BUTTON_INDEX = "SAVED_RADIO_BUTTON_INDEX";
public LoadColor(Context context) {
this.context = context;
}
public void LoadPreferences(){
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View contentView = inflater.inflate(R.layout.activity_settings, null,false);
LayoutInflater tiup = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View homeAct = tiup.inflate(R.layout.activity_home, null,false);
Toolbar tb = (Toolbar) homeAct.findViewById(R.id.toolbarHome);
RadioGroup radioGroup = (RadioGroup) contentView.findViewById(R.id.radioSex);
SharedPreferences sharedPreferences = context.getSharedPreferences("MY_SHARED_PREF", MODE_PRIVATE);
int savedRadioIndex = sharedPreferences.getInt(KEY_SAVED_RADIO_BUTTON_INDEX, 0);
RadioButton savedCheckedRadioButton = (RadioButton) radioGroup.getChildAt(savedRadioIndex);
savedCheckedRadioButton.setChecked(true);
RadioGroup genderGroup = (RadioGroup) contentView.findViewById(R.id.radioSex);
RadioButton male = (RadioButton) contentView.findViewById(R.id.theme1);
RadioButton female = (RadioButton) contentView.findViewById(R.id.theme2);
if (genderGroup.getCheckedRadioButtonId() == -1) {
hA = new HomeActivity();
hA.setToolbarColor(tb, context.getResources().getColor(R.color.colorPrimary));
}
else {
if (male.isChecked()) { // one of the radio buttons is checked
hA = new HomeActivity();
hA.setToolbarColor(tb, context.getResources().getColor(R.color.colorPrimary));
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
((Activity) context).getWindow().setStatusBarColor(Color.parseColor("#014a53"));
}
}
else if (female.isChecked()) {
hA = new HomeActivity();
hA.setToolbarColor(tb, context.getResources().getColor(R.color.colorAccent));
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
((Activity) context).getWindow().setStatusBarColor(Color.parseColor("#db503d"));
}
}
}
}
}
activity_home.xml
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbarHome"
android:layout_width="match_parent"
android:layout_height="64dp"
app:popupTheme="#style/AppTheme.PopupOverlay"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
</android.support.design.widget.AppBarLayout>
HomeActivity.java
private LoadColor Lc;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
//toolbar logo and desc
Toolbar topToolBar = (Toolbar)findViewById(R.id.toolbarHome);
setSupportActionBar(topToolBar); //munculkan menu ke toolbar
topToolBar.setLogo(R.mipmap.ikon);
topToolBar.setLogoDescription(getResources().getString(R.string.logo_desc));
Lc = new LoadColor(this);
Lc.LoadPreferences();
} //OnCreate
public static void setToolbarColor(Toolbar toolbar, #ColorInt int color) {
toolbar.setBackgroundColor(color);
}
You can see the setStatusBarColor code in LoadColor.java it's work, but in the toolbar setBackgroundColor it doesn't work.
Inside your onCreate or wherever you want to change the toolbar color you may call this static utility function and pass it the reference of the toolbar for which you want to change the background. This of course happens after you have identified which color you want to use for the background.
//Tools.java
public static void setToolbarColor(Toolbar toolbar, #ColorInt int color) {
toolbar.setBackgroundColor(color);
}
For example:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
//toolbar logo and desc
Toolbar topToolBar = (Toolbar)findViewById(R.id.toolbarHome);
setSupportActionBar(topToolBar); //munculkan menu ke toolbar
topToolBar.setLogo(R.mipmap.ikon);
topToolBar.setLogoDescription(getResources().getString(R.string.logo_desc));
//determine which color you want to use for the toolbar's background here
//you may use a local method to do that and return the resource value
//it can be an int resource or it can simply be a stored resource.
Tools.setToolbarColor(toolbar,getResources().getColor(R.color.colorPrimary));
//you can also parse the color from a string
setToolbarColor(topToolBar, Color.parse("RED"));
} //OnCreate

How to use Helpshift Embeddable Support Fragments Android

I am building an Android app that uses the Helpshift API. It was all working, but I am currently trying to move everything into a TabLayout, using Fragments and an ActionBar. I made a mini app to figure out functionality of the fragments without messing everything else up. I have a home screen where you click a button and it starts the activity containing the TabLayout with the Fragments. I cannot figure out how to make the embeddable support fragments show up in the TabLayout. I'm pretty new to Android, so sorry if my code is not the best. Right now the placeholder is not being replaced in the fragment transaction, and I can't figure out why. I would greatly appreciate any advice! Thank you :) Let me know if I can provide anything else
Here is my main activity class (Helpshift info has been redacted for privacy reasons, hopefully my issue can still be fixed)
public class MainActivity extends AppCompatActivity {
Context mContext;
public ConstraintLayout layout;
Activity goToFragment;
public Button start;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home_screen);
mContext = getApplicationContext();
goToFragment = MainActivity.this;
start = (Button) findViewById(R.id.button);
start.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick (View view) {
launchFragments();
}
});
//HELPSHIFT SET UP
Core.init(All.getInstance());
InstallConfig installConfig = new InstallConfig.Builder()
.setScreenOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE)
.setEnableInAppNotification(true)
.build();
try {
Core.install(getApplication(),
"****APIKEY*****",
"****DOMAIN*****",
"****APPID******", installConfig);
} catch (InstallException e) {
android.util.Log.e("Helpshift", "install call : ", e);
}
}
private void launchFragments() {
Intent intent1 = new Intent(mContext, HomeTab.class);
intent1.putExtra("fragmentNumber", 0);
startActivity(intent1);
}
}
Here is my ViewPager Adapter class:
public class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager){
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
Here is my fragment activity class:
public class HomeTab extends AppCompatActivity {
// ImageButton FindCareButton;
private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;
public Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = getApplicationContext();
Intent intent1 = getIntent();
int var = intent1.getIntExtra("fragmentNumber", 0);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
viewPager.setCurrentItem(var);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
if (findViewById(R.id.placeholder) != null) {
if (savedInstanceState != null) {
return;
}
Fragment faqFragment = new Fragment();
faqFragment = Support.getFAQsFragment(HomeTab.this);
getSupportFragmentManager().beginTransaction().add(R.id.placeholder, faqFragment).commit();
}
}
private void setupViewPager(ViewPager viewPager){
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new FAQTab(), "FAQ");
viewPager.setAdapter(adapter);
}
}
Here is my FAQTab class:
public class FAQTab extends Fragment {
public FAQTab(){
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.faq_tab, container, false);
}
}
For layouts, my faq_tab layout is an empty FrameLayout with id "placeholder"
My home_screen layout is a ConstraintLayout with a button (id "button")
And here is my activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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"
tools:context="com.example.sasha.fragment_tester.MainActivity">
<android.support.design.widget.AppBarLayout
android:id="#+id/BarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
android:background="?android:attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"/>
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabGravity="fill"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
/>
</android.support.design.widget.CoordinatorLayout>

Passing data between two tab fragments in a SlidingTabslayout

I have an application which has one main activity which in turn hosts two tabs. Each tab is a fragment. The first tab has an editText and a Button and on button press the text entered by the user must be displayed on the second tab fragment which hosts only one textView. I am using a listener to pass the data but for some reason the app crashes when i press the submit button. Any help would be appreciated. Here is my code:
MainActivity.java
public class MainActivity extends AppCompatActivity implements OnEditTextListener {
Toolbar toolbar;
ViewPager pager;
ViewPagerAdapter adapter;
SlidingTabLayout tabs;
CharSequence Titles[] = {"Home", "Events"};
int Numboftabs = 2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Creating The Toolbar and setting it as the Toolbar for the activity
toolbar = (Toolbar) findViewById(R.id.tool_bar);
setSupportActionBar(toolbar);
// Creating The ViewPagerAdapter and Passing Fragment Manager, Titles fot the Tabs and Number Of Tabs.
adapter = new ViewPagerAdapter(getSupportFragmentManager(), Titles, Numboftabs);
// Assigning ViewPager View and setting the adapter
pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(adapter);
// Assiging the Sliding Tab Layout View
tabs = (SlidingTabLayout) findViewById(R.id.tabs);
tabs.setDistributeEvenly(true); // To make the Tabs Fixed set this true, This makes the tabs Space Evenly in Available width
// Setting Custom Color for the Scroll bar indicator of the Tab View
tabs.setCustomTabColorizer(new SlidingTabLayout.TabColorizer() {
#Override
public int getIndicatorColor(int position) {
return getResources().getColor(R.color.ColorPrimary);
}
});
// Setting the ViewPager For the SlidingTabsLayout
tabs.setViewPager(pager);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void OnEditText(String data) {
Tab2 newFragment = (Tab2)adapter.getItem(1);
newFragment.updateDisplay(data);
}
}
Tab1.java
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
public class Tab1 extends Fragment
{
public interface OnEditTextListener {
public void OnEditText(String data);
}
OnEditTextListener editTextListener = null;
EditText edtText;
Button btnSubmit;
String val;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
editTextListener = (OnEditTextListener) activity;
} catch (ClassCastException ex) {
ex.printStackTrace();
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.first_fragment, container, false);
return v;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
edtText = (EditText)getActivity().findViewById(R.id.edtText);
btnSubmit = (Button)getActivity().findViewById(R.id.btnSubmit);
btnSubmit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
val = edtText.getText().toString();
editTextListener.OnEditText(val);
}
});
}
}
Tab2.java
public class Tab2 extends Fragment {
public static final String TAG = "DATA";
public static final String SAVE = "NBHJB";
String newdata = "";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (savedInstanceState != null)
savedInstanceState.getInt(SAVE);
return inflater.inflate(R.layout.second_fragment, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (savedInstanceState != null) {
savedInstanceState.getString(SAVE);
}
}
public void updateDisplay(String data) {
newdata = data;
TextView randomData = (TextView) getActivity().findViewById(R.id.txtView1);
randomData.setText(newdata);
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(SAVE, newdata);
}
MainActivity.xml
<LinearLayout 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:orientation="vertical"
tools:context=".MainActivity">
<include
android:id="#+id/tool_bar"
layout="#layout/tool_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<View
android:layout_height="2dip"
android:background="#color/tabsScrollColor"
android:layout_width="wrap_content" />
<com.example.regi.tabsprove.SlidingTabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/prove"
android:elevation="2dp" />
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"></android.support.v4.view.ViewPager>
</LinearLayout>
second_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="match_parent"
android:orientation="horizontal">
<TextView
android:id="#+id/txtView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:padding="10dp"
android:text="Default Text"
android:textSize="20dp" />
</LinearLayout>
This is the error that I get
java.lang.NullPointerException
at com.example.regi.tabsprove.Tab2.updateDisplay(Tab2.java:36)
at com.example.regi.tabsprove.MainActivity.OnEditText(MainActivity.java:79)
at com.example.regi.tabsprove.Tab1$1.onClick(Tab1.java:51)
at android.view.View.performClick(View.java:4198)
at android.view.View$PerformClick.run(View.java:17158)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4918)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1004)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:771)
at dalvik.system.NativeStart.main(Native Method)
I'm pretty sure that the line Tab2 newFragment = (Tab2)adapter.getItem(1); is creating a new instance of Tab2 instead of giving you the Fragment that you need. You should find a better way to get the instance of the Fragment that has been built to you by the ViewPager; I'm sure that this post can help you.
I found your design a bit complicated than regular data passing. From the logs, the issue is the program unable to find txtView1 in second fragment. It is always a good practice to use bundle for passing data.
I hope the following changes should fix your problem, but that's not the best way to do it.
Declare your TextView next to newData
public static final String TAG = "DATA";
public static final String SAVE = "NBHJB";
String newdata = "";
TextView randomData;
Initialize it in onCreateView()
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (savedInstanceState != null)
savedInstanceState.getInt(SAVE);
View rootView = inflater.inflate(R.layout.second_fragment, container, false);
randomData = (TextView) rootView.findViewById(R.id.txtView1);
return rootView;
}
Change the updateDisplay function
public void updateDisplay(String data) {
newdata = data;
randomData.setText(newdata);
}
Make sure you dont have any other items with same id as txtView1.
Here is the solution to everyone who might be facing the same issue:
public static String makeFragmentName(int containerViewId, long id) {
return "android:switcher:" + containerViewId + ":" + id;
}
public #Nullable
Fragment getFragmentForPosition(int position)
{
String tag = makeFragmentName(pager.getId(), position);
Fragment fragment = getSupportFragmentManager().findFragmentByTag(tag);
return fragment;
}
#Override
public void OnEditText(String data) {
Tab2 tab2 = (Tab2)getFragmentForPosition(1);
tab2.updateDisplay(data);
}
This code goes to MainActivity.java

Android: Navigation-Drawer on all activities

I want to add navigation drawer on all actvities of my Android project. This is the code of the MainActivity:
public class MainActivity extends Activity {
private String[] drawerListViewItems;
private DrawerLayout drawerLayout;
private ListView drawerListView;
private ActionBarDrawerToggle actionBarDrawerToggle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// get list items from strings.xml
drawerListViewItems = getResources().getStringArray(R.array.items);
// get ListView defined in activity_main.xml
drawerListView = (ListView) findViewById(R.id.left_drawer);
// Set the adapter for the list view
drawerListView.setAdapter(new ArrayAdapter<String>(this,
R.layout.drawer_listview_item, drawerListViewItems));
// App Icon
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
//drawerLayout = (DrawerLayout) findViewById(R.drawable.ic_drawer_2);
actionBarDrawerToggle = new ActionBarDrawerToggle(
this, /* host Activity */
drawerLayout, /* DrawerLayout object */
R.drawable.ic_drawer, /* nav drawer icon to replace 'Up' caret */
R.string.drawer_open, /* "open drawer" description */
R.string.drawer_close /* "close drawer" description */
);
// Set actionBarDrawerToggle as the DrawerListener
drawerLayout.setDrawerListener(actionBarDrawerToggle);
getActionBar().setDisplayHomeAsUpEnabled(true);
// just styling option add shadow the right edge of the drawer
drawerLayout.setDrawerShadow(R.drawable.ic_drawer, GravityCompat.START);
drawerListView.setOnItemClickListener(new DrawerItemClickListener());
}
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
actionBarDrawerToggle.syncState();
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
actionBarDrawerToggle.onConfigurationChanged(newConfig);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// call ActionBarDrawerToggle.onOptionsItemSelected(), if it returns true
// then it has handled the app icon touch event
if (actionBarDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
private class DrawerItemClickListener implements ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView parent, View view, int position, long id) {
displayView(position);
drawerLayout.closeDrawer(drawerListView);
}
private void displayView(int position)
{
switch (position)
{
case 0:
secondactivity();
break;
case 1:
Toast.makeText(MainActivity.this, "2", Toast.LENGTH_LONG).show();
break;
case 2:
Toast.makeText(MainActivity.this, "3", Toast.LENGTH_LONG).show();
default:
break;
}
}
}
public void secondactivity (){
Intent cambioActivity;
cambioActivity = new Intent (this, SecondActivity.class);
startActivity(cambioActivity);
}
}
In this code I create the navigation drawer, I want the navigation drawer on all activities, so my Second Activity's code is this:
public class SecondActivity extends MainActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_secondactivity);
}
The navigation drawer is on the first activity but there isn't on other activities, why? Can someone help me?
The easy way is that you should create fragments. If you are ready to for little hard thing then this is for you. It will let you have same navigation drawer in all activities.
Create drawer_n_activity.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<FrameLayout
android:id="#+id/drawer_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<YourDrawer
android:id="#+id/drawer_drawer"
android:layout_width="match_parent"
android:layout_height="fill_parent" >
</YourDrawer>
</RelativeLayout>
Your DrawerActivity.class
public class DrawerActivity extends Activity {
public RelativeLayout fullLayout;
public FrameLayout frameLayout;
#Override
public void setContentView(int layoutResID) {
fullLayout = (RelativeLayout) getLayoutInflater().inflate(R.layout.drawer_n_activity, null);
frameLayout = (FrameLayout) fullLayout.findViewById(R.id.drawer_frame);
getLayoutInflater().inflate(layoutResID, frameLayout, true);
super.setContentView(fullLayout);
//Your drawer content...
}
}
Now, to include same Navigation Drawer in all your activities and mind one more thing, all your activities must extend DrawerActivity
public class MainActivity extends DrawerActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); //layout for 1st activity
}
}
public class SecondActivity extends DrawerActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second_activity); //layout for 2nd activity
}
}
Okay Guys will share my way I do it (in case you are developing project after somebody and there is already tons of activities).
Finally I inflate navigation drawer with one line of code (in onCreate):
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this; //context
//setContentView(R.layout.activity_favorites); // Was so
Utils.inflatedNavigationDrawerView(mContext, R.layout.activity_favorites); // Now is
//...
}
next what is Utils? :
public class Utils{
public static void inflatedNavigationDrawerView(Context context, int layoutId){
// Here get view of clear DrawerLayout
final View drawerLayout = View.inflate(context,R.layout.navigation_drawer_inflator, null);
// Next inflate to it passed layout for activity
final View mainLayout = View.inflate(context,layoutId, (ViewGroup) drawerLayout);
// And finally inflate to it fragment for NavigationDraver
final View fragmentLayout = View.inflate(context,R.layout.navigation_drawer_inflator_fragment, (ViewGroup) drawerLayout);
// Next we should try to get our drawer (should check with casting to each activity you want to insert to)
NavigationDrawerFragment drawerFragment = null;
// this block should be repeated for each activity you want to use in.
if (context instanceof FavoritesActivity){
// Set our pack of inflates to contentview
((FavoritesActivity) context).setContentView(mainLayout);
// And now we get NavigationDrawerFragment
drawerFragment = (NavigationDrawerFragment)
((FavoritesActivity) context).getSupportFragmentManager().findFragmentById(R.id.navigation_drawer_fragment);
}
if(drawerFragment != null){ // if null then we missed some castings for activity used in.
// Finally setup our drawer
drawerFragment.setUpEasy(R.id.navigation_drawer_fragment, (DrawerLayout)drawerLayout.findViewById(R.id.drawer_layout), (Toolbar) mainLayout.findViewById(R.id.app_bar));
}
}
}
If you would like to avoid creation of hamburger in Toolbar then you shoud in setUpEasy place: mDrawerToggle.setDrawerIndicatorEnabled(false);
Here is my sample of setup:
public void setUpEasy(int fragmentId, DrawerLayout drawerLayout, Toolbar toolBar) {
mContainerView = getActivity().findViewById(fragmentId);
mDrawerLayout = drawerLayout;
mDrawerToggle = new ActionBarDrawerToggle(getActivity(), drawerLayout, toolBar, R.string.open, R.string.close){
#Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
if(!mUserLearnedDrawer){
mUserLearnedDrawer = true;
saveToPreferences(getActivity(), Constants.PREFERENCES_LEARNDRAWER_KEY, mUserLearnedDrawer+"");
}
}
#Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
}
};
mDrawerToggle.setDrawerIndicatorEnabled(false); // If false then no hamburger menu.
mDrawerLayout.setDrawerListener(mDrawerToggle);
mDrawerLayout.post(new Runnable() {
#Override
public void run() {
mDrawerToggle.syncState();
}
});
}
and views used:
// navigation_drawer_inflator.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:dragAndDrop="http://schemas.android.com/apk/res-auto"
android:id="#+id/drawer_layout"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.widget.DrawerLayout>
// navigation_drawer_inflator_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/navigation_drawer_fragment"
android:layout_width="#dimen/navigation_drawer_width"
android:layout_height="match_parent"
android:layout_gravity="start"
android:layout_marginTop="56dp"
app:layout="#layout/fragment_navigation_drawer"
tools:layout="#layout/fragment_navigation_drawer" />
Finally if you will implement this - You will be able to insert navigation drawer to any activity on run. Cheers :)
Here's how I did it. Create the helper class. I also added some optional code for the ability to finish() the class.
public class NavDrawerHelper extends ContextWrapper{
public NavDrawerHelper(Context context){
super(context);
}
public void initNav(final DrawerLayout drawerLayout, NavigationView navigationView, Toolbar toolbar, final boolean isFinish){
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
int id = menuItem.getItemId();
switch (id){
case R.id.nav_home:
startActivity(new Intent(getBaseContext(), MainActivity.class));
if (isFinish) ((Activity)getBaseContext()).finish();
drawerLayout.closeDrawers();
break;
case R.id.nav_settings:
startActivity(new Intent(getBaseContext(), SettingsActivity.class));
if (isFinish) ((Activity)getBaseContext()).finish();
drawerLayout.closeDrawers();
break;
}
return true;
}
});
ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(((Activity)getBaseContext()),drawerLayout,toolbar,R.string.drawer_open,R.string.drawer_close){
#Override
public void onDrawerClosed(View v){
super.onDrawerClosed(v);
}
#Override
public void onDrawerOpened(View v) {
super.onDrawerOpened(v);
}
};
drawerLayout.addDrawerListener(actionBarDrawerToggle);
actionBarDrawerToggle.syncState();
}
}
then add this code to all activities. This replaces your existing initNavigationDrawer() method.
public void initNavigationDrawer() {
//views
NavigationView navigationView = findViewById(R.id.navigation_view);
DrawerLayout drawerLayout = findViewById(R.id.drawer);
NavDrawerHelper navDrawerHelper = new NavDrawerHelper(this);
navDrawerHelper.initNav(drawerLayout, navigationView, toolbar, false);
}

Categories

Resources