How could i get ActionBar instance from AppCompatDialogFragment? - android

I need to get ActionBar instance from AppCompatDialogFragment.
public class EditTextFragment extends AppCompatDialogFragment{
EditText etContent;
TextEditedListener textEditedListener;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Black);
//get ActionBar belongs to EditTextFragment
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
if(etContent == null){
etContent = (EditText) inflater.inflate(R.layout.et_content,null);
}
return etContent;
}
interface TextEditedListener{
void onTextEdited(String txt);
}
}
I have try this,but it seems not work.
ActionBar actionBar = ((MyActivity) getContext()).getSupportActionBar();
setCustomActionBar(actionBar);
Thanks for any help

you can get action bar using typecasting to ActionBarActivity context.
Try this,
ActionBar actionBar = ((AppCompatActivity)getActivity()).getSupportActionBar();

I find the likely answer here.So i solve the problem this way .
1.Create My own toolbar //fake_action_bar.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/fake_action_bar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:minHeight="?attr/actionBarSize"
app:navigationIcon="#android:drawable/ic_menu_manage"
android:background="#color/background_material_dark"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light" >
<TextView
android:id="#+id/actionbar_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:maxLines="1"
android:clickable="false"
android:focusable="false"
android:longClickable="false"
android:textStyle="bold"
android:text="title"
android:textSize="18sp"
android:textColor="#FFFFFF" />
</android.support.v7.widget.Toolbar>
2.Add fake_action_bar to my content view
<?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="vertical"
>
<include
android:id="#+id/fake_action_bar"
layout="#layout/fake_action_bar" />
</LinearLayout>
3.Find the action_bar in AppCompatDialogFragment and init it.
public class EditTextFragment extends AppCompatDialogFragment {
ViewGroup mRootView;
Toolbar toolbar;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NORMAL, R.style.AppTheme_NoTitleBar_Blue);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
if (mRootView == null) {
mRootView = (ViewGroup) inflater.inflate(R.layout.et_content, null);
etContent = (EditText) mRootView.findViewById(R.id.et_content);
toolbar = (Toolbar) mRootView.findViewById(R.id.fake_action_bar);
toolbar.inflateMenu(R.menu.menu_add);
toolbar.setNavigationOnClickListener(v -> dismiss());
toolbar.setOnMenuItemClickListener(item -> {
switch (item.getItemId()) {
case android.R.id.home:
dismiss();
return true;
case R.id.item_test:
if (textEditedListener != null) {
textEditedListener.onTextEdited(etContent.getText().toString());
}
dismiss();
return true;
}
return true;
});
}
return mRootView;
}
}

Related

Android floatingactionbutton causing memory leak

I have seen several memory leak posts here and I think this one is a bit different. I have a floatingactionbutton in my fragment, whenever I navigate to another fragment using the Navigation graph the fab is reported to be leaking by leakcanary below is my xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.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/coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragments.store.StoreFragment">
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="#dimen/small_margin"
app:cardElevation="#dimen/normal_elevation"
app:shapeAppearanceOverlay="#style/ShapeAppearanceOverlayLargeCutLeftTopCorner">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="#+id/swipeToRefresh"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<androidx.core.widget.NestedScrollView
android:id="#+id/nestScrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fadingEdge="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ViewStub
android:layout_width="match_parent"
android:id="#+id/layoutCategories"
android:layout_height="wrap_content"
android:inflatedId="#+id/panel_layoutCategories"
android:layout="#layout/store_layout_categories" />
<ViewStub
android:id="#+id/layoutDeals"
android:layout_height="wrap_content"
android:inflatedId="#+id/panel_layoutDeals"
android:layout_width="match_parent"
android:layout="#layout/store_layout_deals" />
<ViewStub
android:id="#+id/layoutCollections"
android:layout_height="wrap_content"
android:inflatedId="#+id/panel_layoutCollections"
android:layout_width="match_parent"
android:layout="#layout/store_layout_collections" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="#+id/btnGoToCart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:text="#string/cart"
android:textColor="#android:color/white"
android:textStyle="bold"
app:backgroundTint="#color/colorAccent"
app:elevation="#dimen/large_elevation"
app:icon="#drawable/ic_shopping_cart_24px"
app:iconTint="#android:color/white"
app:layout_anchor="#id/nestScrollView"
app:layout_anchorGravity="bottom|end"
app:shapeAppearanceOverlay="#style/ShapeAppearanceOverlayLargeCutLeftTopCorner" />
The btnGoToCart is the problematic fab
And my fragment looks like
public class StoreFragment extends Fragment implements View.OnClickListener {
#BindView(R.id.btnGoToCart)
ExtendedFloatingActionButton btnGoToCart;
private StoreFragmentViewModel storeFragmentViewModel;
public StoreFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_store, container, false);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ButterKnife.bind(this, view);
btnGoToCart.setOnClickListener(this);
loadData();
}
private void loadData() {
disposables.add(SharedPreferencesUtils
.getInstance(getContext())
.isLoggedIn()
.subscribeWith(new DisposableSingleObserver<Boolean>() {
#Override
public void onSuccess(Boolean aBoolean) {
if (aBoolean)
storeFragmentViewModel.fetchProductCategories();
}
#Override
public void onError(Throwable e) {
}
}));
}
#Override
public void onStart() {
super.onStart();
}
#Override
public void onStop() {
super.onStop();
//I tried this hoping it would work nothing
btnGoToCart.clearAnimation();
((ViewGroup) btnGoToCart.getParent()).removeView(btnGoToCart);
btnGoToCart = null;
}
#Override
public void onSaveInstanceState(Bundle state) {
super.onSaveInstanceState(state);
}
}
I tried doing this in the onStop
//I tried this hoping it would work nothing
btnGoToCart.clearAnimation();
((ViewGroup) btnGoToCart.getParent()).removeView(btnGoToCart);
btnGoToCart = null;
But it did not work
Below are the snippets from Leak canary
Can you share the ExtendedFloatingActionButton implementation? Maybe your doing something wrong there.
Also if your using ButterKnife in a Fragment you should use:
private Unbinder unbinder;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fancy_fragment, container, false);
unbinder = ButterKnife.bind(this, view);
// TODO Use fields...
return view;
}
#Override public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
BINDING RESET Fragments have a different view lifecycle than
activities. When binding a fragment in onCreateView, set the views to
null in onDestroyView. Butter Knife returns an Unbinder instance when
you call bind to do this for you. Call its unbind method in the
appropriate lifecycle callback.

Data binding, TabLayout and “No view found for id for fragment”

In my Android app I have an Activity with RecyclerView and when the user clicks on an item I call another Activity that has a TabLayout with 2 fragments, each tab for a set of fields to be filled by the user.
When I do not use data binding, all is fine, but when I change the code to use data binding this error message appears:
FragmentManager: No view found for id 0x7f0c0072
(mypackage:id/container) for fragment
ContatosFormFragment2 [...]
FragmentManager: Activity state:
AndroidRuntime: FATAL EXCEPTION: main
java.lang.IllegalArgumentException: No view found for id 0x7f0c0072 (mypackage:id/container) for fragment ContatosFormFragment2 [...] '.
The strange thing is that if I don’t include the ContatosFormFragment1 (so I have only one tab), the ContatosFormFragment2 works...
Also, if I change the tabs order, including ContatosFormFragment2 first an then ContatosFormFragment1, the error message is 'No view found [...] for fragment ContatosFormFragment1'
Note: I'll really aprecciate if you can focus on the main problem, I mean, don't worry about variable names, encapsulation, code style, etc ... This is an initial code that will be improved when working.
Below the code with and without data binding:
My Activity, no changes for data binding
public class ContatosFormActivity extends AppCompatActivity {
public User contato;
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
TextView tNome, tTipo;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_contatos_form);
Utils.initToolbar(this,false);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.container);
setupViewPager(mViewPager);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
Cursor cursor = (new DbController(getBaseContext())).carregaContatoById(getIntent().getIntExtra("contatoId", -1));
contato = new User(cursor.getString(cursor.getColumnIndexOrThrow(DbHelper.NOME)));
contato.setTipoPessoa(cursor.getString(cursor.getColumnIndexOrThrow(DbHelper.TIPO_PESSOA)));
}
private void setupViewPager(ViewPager viewPager) {
SectionsPagerAdapter adapter = new SectionsPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new ContatosFormFragment1(), "Principal");
adapter.addFragment(new ContatosFormFragment2(), "Histórico");
viewPager.setAdapter(adapter);
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
/* constructor + getItem + getCount + getPageTitle ...*/
}}
Code without data binding
public class ContatosFormFragment1 extends Fragment{
private EditText inputName;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_contatos_tab1,container,false);
inputName = (EditText) view.findViewById(R.id.editText);
ContatosFormActivity contatosFormActivity = (ContatosFormActivity)getActivity();
inputName.setText(contatosFormActivity.contato.getNome());
return view;
}
}
public class ContatosFormFragment2 extends Fragment{
private EditText inputName;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_contatos_tab2,container,false);
inputTipoPessoa = (EditText) view.findViewById(R.id.tipo_pessoa);
ContatosFormActivity contatosFormActivity = (ContatosFormActivity)getActivity();
inputTipoPessoa.setText(contatosFormActivity.contato.getTipoPessoa());
return view;
}
}
fragment_contatos_tab1.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="1">
<android.support.design.widget.TextInputLayout
android:id="#+id/input_layout_name"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/editText"
android:layout_gravity="center_horizontal"
android:elegantTextHeight="false"
android:hint="Nome"/>
</android.support.design.widget.TextInputLayout>
</LinearLayout>
fragment_contatos_tab2.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="1">
<android.support.design.widget.TextInputLayout
android:id="#+id/input_layout_tipoPessoa"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/tipo_pessoa"
android:layout_gravity="center_horizontal"
android:elegantTextHeight="false"
android:hint="Tipo de Pessoa"/>
</android.support.design.widget.TextInputLayout>
</LinearLayout>
Code with data binding
public class ContatosFormFragment1 extends Fragment{
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_contatos_tab1,container,false);
ContatosFormActivity contatosFormActivity = (ContatosFormActivity)getActivity();
FragmentContatosTab1Binding binding = DataBindingUtil.setContentView(getActivity(), R.layout.fragment_contatos_tab1);
binding.setContato(contatosFormActivity.contato);
return view;
}
}
public class ContatosFormFragment2 extends Fragment{
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_contatos_tab2,container,false);
ContatosFormActivity contatosFormActivity = (ContatosFormActivity)getActivity();
FragmentContatosTab2Binding binding = DataBindingUtil.setContentView(getActivity(), R.layout.fragment_contatos_tab2);
binding.setContato(contatosFormActivity.contato);
return view;
}
}
fragment_contatos_tab1.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="contato" type="net.simplifiedcoding.retrofitexample.models.User"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.TextInputLayout
android:id="#+id/input_layout_name"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/editText"
android:layout_gravity="center_horizontal"
android:text="#{contato.nome}"
android:elegantTextHeight="false"
android:hint="Nome"/>
</android.support.design.widget.TextInputLayout>
</LinearLayout>
</layout>
fragment_contatos_tab2.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="contato" type="net.simplifiedcoding.retrofitexample.models.User"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.TextInputLayout
android:id="#+id/input_layout_tipoPessoa"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/tipo_pessoa"
android:layout_gravity="center_horizontal"
android:text="#{contato.tipoPessoa}"
android:elegantTextHeight="false"
android:hint="Tipo de Pessoa"/>
</android.support.design.widget.TextInputLayout>
</LinearLayout>
</layout>
I solved changing to this:
public class ContatosFormFragment1 extends Fragment{
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
ContatosFormActivity contatosFormActivity = (ContatosFormActivity)getActivity();
FragmentContatosTab1Binding binding = DataBindingUtil.inflate(
inflater, R.layout.fragment_contatos_tab1, container, false);
View view = binding.getRoot();
binding.setContato(contatosFormActivity.contato);
return view;
}
}
public class ContatosFormFragment2 extends Fragment{
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
ContatosFormActivity contatosFormActivity = (ContatosFormActivity)getActivity();
FragmentContatosTab2Binding binding = DataBindingUtil.inflate(
inflater, R.layout.fragment_contatos_tab2, container, false);
View view = binding.getRoot();
binding.setContato(contatosFormActivity.contato);
return view;
}
}

onClickListener is not working within onCreateView method

Im using the following code to create Floating Action button. Its within a relative layout.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:fab="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/tools"
android:background="#drawable/form_bg">
<android.support.design.widget.FloatingActionButton
android:id="#+id/myFAB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/fab_bg_mini"
app:elevation="4dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/trans_white"
android:gravity="center"
android:orientation="vertical"
android:padding="10dp">
<WebView
android:id="#+id/chart"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</RelativeLayout>
Here is how Im setting the onClickListener for the floating action button within onCreateView method.
public class TrendChart extends Fragment {
private View mRootview;
private static final String URL = "file:///android_asset/taskstatus.html";
private WebView chart;
class InnerWebView extends WebViewClient {
InnerWebView() {
}
public void onPageFinished(WebView view, String url) {
view.loadUrl("javascript: loadTrendChart();");
}
}
public static final TrendChart newInstance(String company_name) {
TrendChart f = new TrendChart();
f.setArguments(new Bundle(1));
return f;
}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
setHasOptionsMenu(true);
mRootview = inflater.inflate(R.layout.trend_chart, null);
this.chart = (WebView) mRootview.findViewById(R.id.chart);
this.chart.getSettings().setJavaScriptEnabled(true);
this.chart.setWebChromeClient(new WebChromeClient());
this.chart.setWebViewClient(new InnerWebView());
refreshWebView();
return mRootview;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
FloatingActionButton myFab = (FloatingActionButton) getActivity().findViewById(R.id.myFAB);
myFab.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Log.d("Clicked","Hello");
}
});
}
private void refreshWebView() {
this.chart.loadUrl(URL);
}
}
The problem is that onClickListener is not getting fired. Why is that so? I tried putting listener within onCreateView method too but still the problem persists. Is there any ways through which I can use floating button within a class that extends Fragments?
You have to put your code when the Activity is fully created as follows :
#Override
public void onActivityCreated(Bundle savedInstanceState)
{
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
FloatingActionButton myFab = (FloatingActionButton) getActivity().findViewById(R.id.myFAB);
myFab.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Log.d("Check","Clicked");
}
});
}
If you have your code on onCreateView() your code should look like this :
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.YOUR_LAYOUT, container, false);
FloatingActionButton myFab = (FloatingActionButton) view.findViewById(R.id.myFAB);
myFab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Do stuff
}
});
return view;
}
EDIT
Change this :
mRootview = inflater.inflate(R.layout.trend_chart, null);
to this :
mRootview = inflater.inflate(R.layout.trend_chart, container, false);

Getting custom layout reference in PreferenceFragmentCompat

I created a preference which has a custom ImageView layout which is something like this:
<Preference
android:key="profile_picture_preference"
android:layout="#layout/layout_profile_picture"></Preference>
My layout is this:
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/profileImageView"
android:layout_width="75dp"
android:layout_height="75dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp"
android:background="#ABCDEF" />
But I don't know how can get a reference to it. I have tried to get it inside onCreateView method by doing this:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = super.onCreateView(inflater, container, savedInstanceState);
ImageView imageView = (ImageView) view.findViewById(R.id.profileImageView);
return view;
}
But ImageView is null.
Thank you for all your help.
I did not find any offical way. So I managed like this:
#Override
public RecyclerView onCreateRecyclerView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
recyclerView = super.onCreateRecyclerView(inflater, parent, savedInstanceState);
recyclerView.addOnChildAttachStateChangeListener(new RecyclerView.OnChildAttachStateChangeListener() {
#Override
public void onChildViewAttachedToWindow(View view) {
if (view.getId() == R.id.profileImageView) {
profileImageView = (ImageView) view;
}
}
#Override
public void onChildViewDetachedFromWindow(View view) {
}
});
return recyclerView;
}
You can specify a custom layout in your theme. There you could add your ImageView
For example:
styles.xml
<style name="YourTheme" parent="Theme.AppCompat">
<!-- ... -->
<item name="preferenceTheme">#style/YourTheme.PreferenceThemeOverlay</item>
</style>
<style name="YourTheme.PreferenceThemeOverlay" parent="#style/PreferenceThemeOverlay">
<item name="android:layout">#layout/fragment_your_preferences</item>
</style>
fragment_your_preferences.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/profileImageView"
android:layout_width="75dp"
android:layout_height="75dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp"
android:background="#ABCDEF" />
<!-- Required ViewGroup for PreferenceFragmentCompat -->
<FrameLayout
android:id="#+id/list_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</FrameLayout>
</LinearLayout>
And then in onViewCreated() of your fragment class you can start using the ImageView:
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
ImageView image_view = (ImageView)view.findViewById(R.id.profileImageView);
if (image_view != null)
{
// Your code
}
}
I have spent my day trying to solve this... Here is my answer : I have been using onCreateView instead of onCreatePreferencesto load the view :
public static class MyFragment extends PreferenceFragmentCompat {
#Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
//setPreferencesFromResource(R.xml.my_fragment_xml, rootKey); //remove this (!)
}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.my_layout, container, false); //root layout from the fragment xml
view myView = view.findViewById(R.id.myView); //this works (!)
return view;
}
}

NullPointerException when trying to use a listener for FAB

I'm trying to put a FAB in a ViewPager tab, but I get this error (and only this):
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.design.widget.FloatingActionButton.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
It was wroking fine when I had the FAB in the activity_main.xml
MainActiviy:
private FloatingActionButton fabButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
// Initializing Floating Action Button
fabButton = (FloatingActionButton) findViewById(R.id.fabButton);
fabButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Snackbar.make(v, "FAB was pressed!", Snackbar.LENGTH_SHORT)
.setAction("Undo", new View.OnClickListener() {
#Override
public void onClick(View v) {
}
})
.show();
}
});
...
}
PageFragment used to sort the different tabs:
public class PageFragment extends Fragment {
public static final String ARG_PAGE = "ARG_PAGE";
private int mPage;
public static PageFragment newInstance(int page) {
Bundle args = new Bundle();
args.putInt(ARG_PAGE, page);
PageFragment fragment = new PageFragment();
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPage = getArguments().getInt(ARG_PAGE);
System.out.println(">> mPage = " + mPage); //Testing
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
SampleFragmentPagerAdapter sampleFragmentPagerAdapter = new SampleFragmentPagerAdapter(getFragmentManager(), getContext());
View view;
switch (mPage) {
case 1:
view = inflater.inflate(R.layout.tab1_frag, container, false);
return view;
case 2:
view = inflater.inflate(R.layout.tab2_frag, container, false);
return view;
case 3:
view = inflater.inflate(R.layout.tab3_frag, container, false);
return view;
default:
view = inflater.inflate(R.layout.fragment_page, container, false);
return view;
}
}
}
tab_2frag xml file for the particular tab:
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<FrameLayout
android:id="#+id/frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Tab 2"
android:textSize="40sp" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/fabButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_marginBottom="#dimen/fab_margin_bottom"
android:layout_marginEnd="#dimen/fab_margin_end"
android:src="#mipmap/ic_add_white_24dp"
app:fabSize="normal" />
</FrameLayout>
can anyone help?
Dont use listener.
In your xml:
android:onClick:"nameOfMethod"
In your Activity:
public void nameofMethod(View v){
//button Clicked
}
Your FloatingActionButton is in a fragment layout, but you are trying to find it in the MainActivity's onCreate(). findViewById(R.id.fabButton) returns null and thus causing the error when you set a click listener on it in the MainActivity.
You may call it in the onCreateView() of the fragment instead if you want to do it programatically
view = inflater.inflate(R.layout.tab2_frag, container, false);
fabButton = (FloatingActionButton) view.findViewById(R.id.fabButton);
fabButton.setOnClickListener(new View.OnClickListener() {...} );
return view;

Categories

Resources