How triggered onOptionsItemSelected (menuItemTransmitMeterReading) from Fragment in Activity click button(btnTransmit). I need the button to do the same as the menuItem. Put all extraStings and start new activity. I'm new in android and fragments are very hard for me.
Fragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.account_detail, container, false);
if (mItem != null) {
((TextView) rootView.findViewById(R.id.account_detail)).setText(mItem.details);
}
return rootView;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.menu_account, menu);
menuItemAccountDelete = menu.findItem(R.id.action_account_delete);
menuItemTransmitMeterReading = menu.findItem(R.id.action_transmit_meter_readings);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.equals(menuItemAccountDelete)) {
FragmentManager manager = getActivity().getSupportFragmentManager();
MyDeleteAccountDialog myDialog = new MyDeleteAccountDialog();
myDialog.LS = mItem.ls;
myDialog.show(manager, "dialog");
} else if (item.equals(menuItemTransmitMeterReading)) {
Intent intent = new Intent(getActivity(), ActivityAccountTransmitMeterReading.class);
intent.putExtra(ACCOUNT_LS, mItem.ls);
intent.putExtra(ACCOUNT_NUMBER_OF_ZONES, mItem.MeterZonesCount);
intent.putExtra(ACCOUNT_LAST_METER_READING, mItem.LastMeterReading);
intent.putExtra(ACCOUNT_METER_NUMBER_OF_DIGITS, mItem.MeterNumberOfDigits);
intent.putExtra(ACCOUNT_ADDRESS, mItem.Address);
intent.putExtra(ACCOUNT_RMES, mItem.R_mes);
intent.putExtra(ACCOUNT_FKVT1, mItem.FKVT1);
intent.putExtra(ACCOUNT_FKVT2, mItem.FKVT2);
intent.putExtra(ACCOUNT_FKVT3, mItem.FKVT3);
intent.putExtra(ACCOUNT_FIO, mItem.fio);
if(mItem.LastMeterReading.contains("TEST")){
FragmentManager manager = getActivity().getSupportFragmentManager();
MyTransmitMeterReadingDialog myTransmitMeterReadingDialog = new MyTransmitMeterReadingDialog();
myTransmitMeterReadingDialog.show(manager,"dialog");
}
else {
startActivityForResult(intent, REQUEST_ACCOUNT_TRANSMIT_METER_READING);
}
}
return super.onOptionsItemSelected(item);
}
layoutFragment.xml
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/account_detail"
style="?android:attr/textAppearanceLarge"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="0dp"
android:textIsSelectable="true"
tools:context="local.soe.itps02.soebilling.FragmentAccountDetail" /><br>
layoutActivity.xml
<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"
android:fitsSystemWindows="true"
tools:context="local.soe.itps02.soebilling.ActivityAccountDetail"
tools:ignore="MergeRootFrame">
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/detail_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="70dp">
<Button
android:id="#+id/btnTransmit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="OnActionButtonClick"
android:layout_weight="1"
android:text="Transmit" />
<Button
android:id="#+id/btnPay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="OnActionButtonClick"
android:layout_weight="1"
android:text="Pay"
/>
</LinearLayout>
<android.support.v4.widget.NestedScrollView
android:id="#+id/account_detail_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="65dp"
android:overScrollMode="never"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
Like i said in comments you can do this, first inside mainActivity create this method:
public void startintent(){
Intent intent = new Intent(MainActivity.this, ActivityAccountTransmitMeterReading.class);
intent.putExtra(ACCOUNT_LS, mItem.ls);
intent.putExtra(ACCOUNT_NUMBER_OF_ZONES, mItem.MeterZonesCount);
intent.putExtra(ACCOUNT_LAST_METER_READING, mItem.LastMeterReading);
intent.putExtra(ACCOUNT_METER_NUMBER_OF_DIGITS, mItem.MeterNumberOfDigits);
intent.putExtra(ACCOUNT_ADDRESS, mItem.Address);
intent.putExtra(ACCOUNT_RMES, mItem.R_mes);
intent.putExtra(ACCOUNT_FKVT1, mItem.FKVT1);
intent.putExtra(ACCOUNT_FKVT2, mItem.FKVT2);
intent.putExtra(ACCOUNT_FKVT3, mItem.FKVT3);
intent.putExtra(ACCOUNT_FIO, mItem.fio);
}
And inside button onclickListener or onOptionsItemSelected() just call this:
startintent()
Or if you want to call in fragment inside button onclickListener or onOptionsItemSelected():
MainActivity.startintent()
Related
I'm making a Bottom Navigation View.
Show fragments when switching screens.
However, when switching to Fragment, the icon at the top right (Option menu) is not visible.
As a solution for similar reasons, I added setHasOptionsMenu(true), but the options menu is still not visible.
MainActivity.xml
<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"
tools:context=".activity.MainActivity">
<FrameLayout
android:id="#+id/content_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toTopOf="#id/bottom_nav"/>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottom_nav"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="?android:attr/windowBackground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="#menu/bottom_nav_menu"/>
</androidx.constraintlayout.widget.ConstraintLayout>
fragment.java
public class WorkoutListFragment extends Fragment {
RecyclerView rcv_dailyRecord;
TextView mainNotifyText;
Toolbar toolbar;
LinearLayoutManager lm;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.activity_workout_list, container, false);
initViews(rootView);
setHasOptionsMenu(true);
return rootView;
}
public void initViews(View v) {
rcv_dailyRecord = v.findViewById(R.id.rcv_dailyrecord);
toolbar = v.findViewById(R.id.toolbar);
mainNotifyText = v.findViewById(R.id.main_notification_text);
}
#Override
public void onCreateOptionsMenu(#NonNull Menu menu, #NonNull MenuInflater inflater) {
inflater = getActivity().getMenuInflater();
inflater.inflate(R.menu.record_item_add, menu);
}
}
fragment.xml
<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"
tools:context=".activity.WorkoutListActivity">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="#+id/coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:elevation="0dp"
android:theme="#style/Theme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:title="LIST"
app:titleTextColor="#color/black"
app:titleMarginStart="30dp"
android:paddingRight="30dp"
android:theme="#style/Theme.PopupOverlay"/>
</com.google.android.material.appbar.AppBarLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toBottomOf="#id/toolbar"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
<TextView
android:id="#+id/main_notification_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="CHOOSE WORKOUT"
android:textSize="16dp"
android:gravity="center"
android:layout_gravity="center"
android:textColor="#color/orgin_text_color"/>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rcv_dailyrecord"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:layout_marginLeft="10dp"
android:scrollbars="vertical" />
</FrameLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
menu.xml
<menu 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">
<item
android:icon="#drawable/ic_action_add"
android:title="A D D"
app:showAsAction="always" />
</menu>
Try overriding onCreate function in your Fragment and calling setHasOptionsMenu function there, like this:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
For the difference between onCreate and onCreateView you can read more in this stackoverflow thread.
Try with this because you have a custom toolbar in your Fragment,
just add your toolBar into your activity and setHasOptionMenu(true).
add this in your onCreate method:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_blank, container, false);
initViews(rootView);
((AppCompatActivity) requireActivity()).setSupportActionBar((toolbar));
setHasOptionsMenu(true);
return rootView;
}
I am having a bottom tabbed activity with Home, Dashboard and Notifications tabs. Now by default android studio offers these tabs in the form of fragments. I have a button that is inside a fragment_home.xml but my current view is set to activity_main.xml.The button.onClick Listener inside fragment class does not seem to work. How can this be resolved?
Main Class...
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BottomNavigationView navView = findViewById(R.id.nav_view);
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications).build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
NavigationUI.setupWithNavController(navView, navController);
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayShowCustomEnabled(true);
View cView = getLayoutInflater().inflate(R.layout.cutom_toolbar, null);
actionBar.setCustomView(cView);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu, menu);
return super.onCreateOptionsMenu(menu);
}
boolean doubleBackToExitPressedOnce = false;
#Override
public void onBackPressed() {
if (doubleBackToExitPressedOnce) {
super.onBackPressed();
return;
}
this.doubleBackToExitPressedOnce = true;
Toast.makeText(this, "Please click BACK again to exit", Toast.LENGTH_SHORT).show();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
doubleBackToExitPressedOnce=false;
}
}, 2000);
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId()){
case R.id.menu1:
Toast.makeText(this, "Clicked Menu 1", Toast.LENGTH_SHORT).show();
break;
case R.id.menu2:
Toast.makeText(this, "Clicked Menu 2", Toast.LENGTH_SHORT).show();
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
}
activity_main.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:grid="http://schemas.android.com/apk/res-auto"
android:id="#+id/container"
android:layout_width="match_parent"
android:background="#drawable/image"
android:layout_height="match_parent"
android:paddingTop="?attr/actionBarSize"
grid:alignmentMode="alignBounds"
grid:columnCount="2"
grid:rowOrderPreserved="false"
grid:useDefaultMargins="true">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/nav_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:background="#drawable/image1"
app:itemIconTint="#color/color"
app:itemTextColor="#color/color"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="#menu/bottom_nav_menu" />
<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_constraintBottom_toTopOf="#id/nav_view"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/mobile_navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>
fragment_home.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:grid2="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.gridlayout.widget.GridLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="?attr/actionBarSize"
grid2:alignmentMode="alignBounds"
grid2:columnCount="2"
grid2:rowOrderPreserved="false">
<LinearLayout
android:id="#+id/layout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:text="TextView"
grid2:layout_column="0"
grid2:layout_row="0">
<LinearLayout
android:id="#+id/l1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:text="Lighting"
android:textSize="21sp"
android:textStyle="italic"
grid2:layout_column="0"
grid2:layout_gravity="fill"
grid2:layout_row="0">
<Button
android:id="#+id/imageView2"
android:layout_width="80dp"
android:layout_height="70dp"
android:layout_gravity="center"
android:background="#drawable/light2"
grid2:layout_gravity="left" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="5dp"
android:textStyle="italic" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="All Off"
android:textSize="14sp" />
</LinearLayout>
</LinearLayout>
</androidx.gridlayout.widget.GridLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Fragment Class...
public class Fragment1 extends Fragment implements View.OnClickListener{
public Button button;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_home, container, false);
button = view.findViewById(R.id.imageView2);
button.setOnClickListener(this);
return view;
}
#Override
public void onClick(View view) {
button.setVisibility(View.GONE);
}
}
Not clear. if i am getting right then,
declare a global veriable inside your fragment.
public Button button;
initialize it to onViewCreated()
in your main activity
if(fragment.button != null){
//fire action
}
The view elements that are declared in fragment_home.xml will need to be interacted with in the Fragment code and not the activity.
Using the NavHost means most of your code will be in the individual fragments and not in the activity hosting the fragments.
You could use an interface to communicate between the two if necessary.
You could also use a shared ViewModel to communicate - have the onClick listener in the fragment set an Observable in the ViewModel that the MainActivity is subscribed to.
I am having troubling sending data from one fragment to another fragment. I was following the android guideline which tells me to create an interface to communicate with activity and fragments. I'm using the bottom navigation to switch over fragments.
Anyway, here's the error from android studio:
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.makkhay.cameratranslate.Favorite.displayReceivedData(java.lang.String)' on a null object reference
at com.example.makkhay.cameratranslate.HomeActivity.sendData(HomeActivity.java:143)
at com.example.makkhay.cameratranslate.HomeFragment$2.onClick(HomeFragment.java:162)
at android.view.View.performClick(View.java:6256)
at android.view.View$PerformClick.run(View.java:24697)
at android.os.Handler.handleCallback(Handler.java:789)
For some reason, my fragments are always null even after initializing it. I tried initializing it both ways, onCreate method, and the sendData method, the instance always seems to be null. I think the main culprit might be the DrawerLayout. Since it is the parent xml and there is another xml called "app_bar_home.xml"; which is hosting the two fragments using bottom navigation, the newly created instances are always null
Here's my main activity which is holding two fragments
HomeActivity.java
public class HomeActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener,HomeFragment.SendMessage {
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_favorite:
selectedFragment = new Favorite();
break;
}
getSupportFragmentManager().beginTransaction().replace(R.id.app_bar,
selectedFragment).commit();
return true;
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
//I added this if statement to keep the selected fragment when rotating the device
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction().replace(R.id.app_bar,
new HomeFragment()).commit();
}
}
#Override
public void sendData(String message) {
Favorite f = (Favorite) getSupportFragmentManager().findFragmentById(R.id.favFragment);
f.displayReceivedData(message);
}
}
Here's my xml for my activity
activity_home.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.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">
<include
android:id="#+id/app_bar"
layout="#layout/app_bar_home"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_home"
app:menu="#menu/activity_home_drawer" />
</android.support.v4.widget.DrawerLayout>
Here's the app_bar_home.xml which is also part of the activity
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".HomeActivity">
<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:layout_width="match_parent"
android:layout_height="?actionBarSize"
app:layout_collapseMode="pin"
android:id="#+id/toolbar"
/>
</android.support.design.widget.AppBarLayout>
<android.support.design.widget.BottomNavigationView
android:id="#+id/navigation"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="0dp"
android:layout_marginStart="0dp"
app:layout_constraintBottom_toBottomOf="parent"
android:background="#000"
app:itemIconTint="#color/color_selector"
app:itemTextColor="#color/color_selector"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="#menu/navigation" />
</android.support.constraint.ConstraintLayout>
Here's the fragment 1 from which I want to send the data to another fragment.
HomeFragment.java
public class HomeFragment extends Fragment implements View.OnClickListener{
SendMessage SM;
private Button clearButton, favButton, shareButton;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_home, container, false);
return v;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
favButton = view.findViewById(R.id.favButton);
favButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SM.sendData(" test");
}
});
}
interface SendMessage {
void sendData(String message);
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
try {
SM = (SendMessage) getActivity();
} catch (ClassCastException e) {
throw new ClassCastException("Error in retrieving data. Please try again");
}
}
}
HomeFragment.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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:id="#+id/homeFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".HomeFragment"
>
<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/toolbar"
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
app:layout_collapseMode="pin" />
</android.support.design.widget.AppBarLayout>
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="6dp"
android:layout_marginEnd="6dp"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:layout_marginStart="6dp"
android:layout_marginTop="56dp"
android:background="#drawable/card_shadow"
android:divider="?android:dividerHorizontal"
android:paddingTop="6dp"
android:paddingBottom="6dp"
android:showDividers="middle">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingBottom="16dp"
android:gravity="right"
android:orientation="vertical">
<Button
android:id="#+id/favButton"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginTop="4dp"
android:background="#drawable/ic_favorite_black_12dp"
/>
</LinearLayout>
</LinearLayout>
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
Finally here's the 2nd fragment where I want to recieve the data
Favorite.java
public class Favorite extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_favorite, container, false);
favText = v.findViewById(R.id.tv_recycler_item_1);
return v;
}
protected void displayReceivedData(String message)
{
Toast.makeText(getContext(),"rec:" + message,Toast.LENGTH_SHORT).show();
}
}
fragment_favorite.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:id="#+id/favFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".Favorite">
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar_scrolling"
android:layout_width="match_parent"
android:layout_height="180dp"
android:fitsSystemWindows="true"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsing_toolbar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:scaleType="centerCrop"
android:src="#drawable/bg_red" />
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/Widget.AppCompat.PopupMenu.Overflow" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
>
<TextView
android:id="#+id/txtData"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="548dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/recycler_view_recycler_view"
app:layout_constraintStart_toStartOf="parent" />
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view_recycler_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="382dp"
android:layout_marginEnd="344dp"
android:layout_marginRight="344dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
</android.support.v7.widget.RecyclerView>
</android.support.constraint.ConstraintLayout>
</android.support.design.widget.CoordinatorLayout>
Let me know if you need more info. thanks in advance :)
you can pass data between fragment by putting as argument in bundle like following:
Fragment fragment = new Fragment();
Bundle bundle = new Bundle();
bundle.putInt(key, value);
fragment.setArguments(bundle);
For retrieving you can do following
Bundle bundle = this.getArguments();
if (bundle != null) {
int myInt = bundle.getInt(key);
}
On my view best way of communication is by using EventBus between Activity-fragment, fragment-fragment, Activity-Activty, very easy and less complicated
Here is an Example
Create a model of what you want to share, so here is model for sending string declare the string variable use constructor and getter for setting and getting message
public MessageEvent(String Message)
{
this.msg=msg;
}
public String getMsg() {
return msg;}
Now in your fragment 1 post the message before that register eventbus on OnAttach and deregister it in OnDettach
EventBus.getDefault().post(new MessageEvent("My Message));
In Fragment 2 get the message in OnEvent Method(even in this fragment don't forget to register and deregister Event Bus)
#Subscribe
public void onEvent(MessageEvent event) {
this.msg=event.getMsg();
callTheMethodToDoYourOperation(msg);
}
This a basic example, but check about event bus before using this and moreover in both fragment you require to Register, deregister and subscribe onevent, and if this is one way communication let onEvent be empty
Hope this helps
The NullPointerException occurred because your Fragment is not initialized yet, so before interacting with is make sure you check is it initialized and visible or not.
if (f!= null && f.isVisible()) {
f.displayReceivedData(message);
}
You can also use Bundle to pass data between Fragment too.
Note: Before posting question understand the error and try to debug the root cause of the error. You'll definitely solve it on your own.
Happy coding :)
You are getting Null pointer on method where you receive data, that fragment instance is null. Favorite f is null.
Create one instance if that fragment and then call .replace
I have an activity which has a MaterialDrawer created. The material Drawer code is as follows
SecondaryDrawerItem item1 = new SecondaryDrawerItem().withIdentifier(1).withName(R.string.drawer_item_home)
.withIcon(new IconicsDrawable(this)
.icon(GoogleMaterial.Icon.gmd_home)
.sizeRes(R.dimen.activity_horizontal_margin));
SecondaryDrawerItem item2 = new SecondaryDrawerItem().withIdentifier(2).withName(R.string.drawer_item_graph)
.withIcon(new IconicsDrawable(this)
.icon(GoogleMaterial.Icon.gmd_trending_up)
.sizeRes(R.dimen.activity_horizontal_margin));
SecondaryDrawerItem item3 = new SecondaryDrawerItem().withIdentifier(3).withName(R.string.drawer_item_map)
.withIcon(new IconicsDrawable(this)
.icon(GoogleMaterial.Icon.gmd_map)
.sizeRes(R.dimen.activity_horizontal_margin));
SecondaryDrawerItem item4 = new SecondaryDrawerItem().withIdentifier(4).withName(R.string.drawer_item_settings)
.withIcon(new IconicsDrawable(this)
.icon(GoogleMaterial.Icon.gmd_settings)
.sizeRes(R.dimen.activity_horizontal_margin))
.withSelectable(false);
new DrawerBuilder()
.withActivity(this)
.withToolbar(getToolbar())
.withSelectedItem(1)
.withAccountHeader(headerResult)
.withActionBarDrawerToggleAnimated(true)
.addDrawerItems(
item1,
item2,
item3,
new DividerDrawerItem(),
item4
)
.withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() {
#Override
public boolean onItemClick(View view, int position, IDrawerItem drawerItem) {
// do something with the clicked item :D
if (drawerItem != null) {
if (drawerItem.getIdentifier() == 1) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment, new WeatherFragment())
.commit();
}
else if (drawerItem.getIdentifier() == 2) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment, new GraphsFragment())
.commit();
}
else if (drawerItem.getIdentifier() == 3) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment, new MapsFragment())
.commit();
}
else if (drawerItem.getIdentifier() == 4) {
startActivity(new Intent(WeatherActivity.this, AboutActivity.class));
}
}
return false;
}
})
.build();
When my app starts, the default option selected is 1, ie. the activity automatically loads WeatherFragment when the App is started. The problem occurs when I click on the Second item in the list : Graphs Fragment. According to the code, it should have worked, but what it does is it retains the old fragment in view, and does not load the layout of the new Fragment.
Here is the Activity XML Layout:
<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"
android:background="#color/colorPrimary"
tools:context="com.a5corp.weather.activity.WeatherActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.NoActionBar.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.NoActionBar.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_weather" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/fab_margin"
app:srcCompat="#drawable/ic_search_white_24dp" />
</android.support.design.widget.CoordinatorLayout>
content_weather.xml :
<fragment 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/fragment"
android:name="com.a5corp.weather.fragment.WeatherFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:layout="#layout/fragment_weather" />
Until now, what is clear is that WeatherActivity will always load fragment_weather (WeatherFragment) as such. But when I click on the GraphsFragment (second item), it does not load that layout
Here is my GraphsFragment code:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
Log.i("Loaded" , "Fragment"); //This Log info shows up in the Android Logger
rootView = inflater.inflate(R.layout.fragment_graphs, container, false);
return rootView;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MaterialDialog.Builder builder = new MaterialDialog.Builder(this.getActivity())
.title("Please Wait")
.content("Loading")
.progress(true , 0);
builder.build().show();
}
fragment_graphs.xml :
<android.support.v4.widget.SwipeRefreshLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="111dp"
android:text="Button"/>
<Switch
android:id="#+id/switch1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignStart="#+id/button2"
android:layout_below="#+id/button2"
android:layout_marginTop="40dp"
android:text="Switch"/>
</RelativeLayout>
</android.support.v4.widget.SwipeRefreshLayout>
The progress dialog shows as such, but the layout items like the button and the switch from GraphsFragment XML do not load.
How will I load the GraphsFragment when clicked from the Drawer, along with the layout inflated and the progress dialog shown
Turns out I only needed to add a FrameLayout instead of includeing the layout.
Here is the modified main XML file
<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"
android:background="#color/colorPrimary"
tools:context="com.a5corp.weather.activity.WeatherActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/appBar"
android:theme="#style/AppTheme.NoActionBar.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.NoActionBar.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/fragment"
android:paddingTop="?attr/actionBarSize"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.a5corp.weather.WeatherActivity"
tools:ignore="MergeRootFrame"
android:background="#color/colorPrimary" />
</android.support.design.widget.CoordinatorLayout>
I'm trying to switch from an Activity with a fragment without a Toolbar (R.id.main_screen) to one that has a Toolbar (R.id.source_items_list).
However, whenever I have a Toolbar in R.id.source_items_list, it crashes. The error I'm getting is
android.view.InflateException: Binary XML file line #10: Error
inflating class android.support.v7.widget.Toolbar
which comes from the line
View view = inflater.inflate(R.layout.fragment_sourceitem_list, viewGroup, false); in the following code.
I wonder what I'm doing wrong. Here's my code.
public class MainActivity extends FragmentActivity implements MainFragment.OnFragmentInteractionListener {
...
#Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
// set uncaught exception handler for thread
// Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(this));
setContentView(R.layout.activity_main);
FragmentManager fragmentManager = getSupportFragmentManager();
mMainFrame = MainFragment.newInstance();
fragmentManager.beginTransaction().add(R.id.container, mMainFrame).commit();
}
#Override
public void onFragmentInteraction(int id) {
FragmentManager fragmentManager = getSupportFragmentManager();
switch (id) {
case R.id.button_sources:
Fragment fragment = new SourceListFragment();
FragmentTransaction fragmentTrans = fragmentManager.beginTransaction();
fragmentTrans.replace(R.id.container, fragment);
fragmentTrans.addToBackStack(null);
fragmentTrans.commit();
break;
default:
break;
}
}
}
public class SourceListFragment extends Fragment implements AbsListView.OnClickListener {
...
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup viewGroup, Bundle savedInstanceState) {
Log.d("SOURCELIST", "SourceListFragment onCreateView\n");
View view = inflater.inflate(R.layout.fragment_sourceitem_list, viewGroup, false);
return view;
}
public static SourceListFragment newInstance(BluetoothAdapter adapter) {
SourceListFragment fragment = new SourceListFragment();
mBTAdapter = adapter;
return fragment;
}
// Container Activity must implement this interface
public interface OnFragmentInteractionListener {
public void onFragmentInteraction(int id);
}
}
Here's the layout:
activity_main.xml:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:materialdesign="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:background="#FFF"
android:orientation="vertical"
android:id="#+id/container">
</FrameLayout>
fragment_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/main_screen"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="148dp">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="128dp"
android:background="#01579b"
android:paddingBottom="20dp"
android:paddingLeft="104dp" android:id="#+id/banner">
</RelativeLayout>
</RelativeLayout>
<android.support.percent.PercentRelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/button_sources"
app:layout_widthPercent="30%"
app:layout_heightPercent="30%"
app:layout_marginTopPercent="10%"
app:layout_marginLeftPercent="15%"
app:layout_marginRightPercent="5%"/>
...
</android.support.percent.PercentRelativeLayout>
</LinearLayout>
fragment_sourceitem_list.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:id="#+id/source_items_list"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/toolbar"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:background="?attr/colorPrimary"/>
<ListView android:id="#android:id/list" android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<com.gc.materialdesign.views.ProgressBarCircularIndeterminate
android:id="#+id/progressBarCircularIndeterminate"
android:layout_width="32dp"
android:layout_height="32dp"
android:background="#1E88E5" />
</FrameLayout>
Any help will be appreciated.
Thanks