add a header to fragmentlist android - android

I'm adding a header to my ListFragment but header doesn't appear. I tried add in onCreate and onStart but I already set my adapter. I found here this Best place to addHeaderView in ListFragment but it is not valid.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = getActivity().getLayoutInflater().inflate(R.layout.header,
null);
container.addView(v,0);
rla = new RowListAdapter(getActivity().getLayoutInflater(),
R.layout.itemlayout, rl);
setListAdapter(rla);
return super.onCreateView(inflater, container, savedInstanceState);
}
#Override
public void onStart() {
super.onStart();
getListView().setBackgroundResource(R.color.tostadoclaro);
getListView()
.setDivider(getResources().getDrawable(R.drawable.divider));
getListView().setDividerHeight(4);
}
¡¡¡SOLUTION!!!
#Override
public void onActivityCreated(Bundle savedInstanceState) {
View v = getActivity().getLayoutInflater().inflate(R.layout.header,
null);
this.getListView().addHeaderView(v);
rla = new RowListAdapter(getActivity().getLayoutInflater(),
R.layout.itemlayout, rl);
setListAdapter(rla);
super.onActivityCreated(savedInstanceState);
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState){// Empty. Use original.}

Don't add the view to the container. Use addHeaderView(v).

The complete code (adapted from here):
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
TextView tv = new TextView(getActivity());
tv.setText("Hello");
getListView().addHeaderView(tv);
setListAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1,
new String[] { "Hello world" }));
}
#Override
public void onDestroyView() {
setListAdapter(null);
super.onDestroyView();
}
See also: Best place to addHeaderView in ListFragment

Related

Can't change fragment text view from a method

I'm trying this simple method to change a fragment text view but the app crashes every time I try to open the activity of the fragment with this fragment code
public class FragmentContrat extends Fragment {
public FragmentContrat() {}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.contrat_fragment, container, false);
update();
return view;
}
public void update() {
TextView textView = (TextView)getView().findViewById(R.id.souscripteur_txt);
textView.setText("milan");
}
however it works fine and the TextView change when I put the same code in onCreateView like this :
public class FragmentContrat extends Fragment {
public FragmentContrat() {}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.contrat_fragment, container, false);
TextView textView = (TextView)view.findViewById(R.id.souscripteur_txt);
textView.setText("milan");
return view;
}
the activity code :
public class DetailsContrat extends AppCompatActivity {
TabLayout details_tab;
AppBarLayout details_bar;
ViewPager details_pager;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_details_contrat);
Intent i = getIntent();
String client_id = i.getStringExtra("client_id");
details_tab=(TabLayout)findViewById(R.id.details_tab);
details_bar=(AppBarLayout) findViewById(R.id.details_bar);
details_pager=(ViewPager)findViewById(R.id.details_pager);
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
FragmentContrat fragmentContrat = new FragmentContrat();
FragmentVehicule fragmentVehicule = new FragmentVehicule();
FragmentGaranties fragmentGaranties = new FragmentGaranties();
adapter.AddFragment(fragmentContrat,"MON CONTRAT");
adapter.AddFragment(fragmentVehicule,"MA VOITURE");
adapter.AddFragment(fragmentGaranties,"MES GARANTIES");
details_pager.setAdapter(adapter);
details_tab.setupWithViewPager(details_pager);
}
}
In onCreateView you are creating and the fragment's view. So if you call getView(), to get the fragment view you will get null, because you haven't yet returned the just created view.
You can:
Use the newly-created view similarly to what #Sanjaysinh's is recommending
Avoid setting your text in onCreateView and set it in onViewCreated(View view, Bundle savedInstanceState), that is called after the view has been created (docs)
I think you need to pass your view in update method
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.contrat_fragment, container, false);
update(view);
return view;
}
public void update(View view) {
TextView textView = (TextView)view.findViewById(R.id.souscripteur_txt);
textView.setText("milan");
}

How to make BottomSheetDialogFragment cover the full screen?

I'm using BottomSheetDialogFragment to show some data.But when I'm starting the fragment it's appearing 50% of the screen .So, my question is how to make it full screen when it shows.
BottomSheetDialogFragment Code:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.bot_frag, container, false);
TextView tv = v.findViewById(R.id.textVi);
back=v.findViewById(R.id.back_of_bot);
back.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
dismiss();
}
}
);
return v;
}
You can use dialog fragments, plz refer this:
public class DialogFragments extends DialogFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);
View view = inflater.inflate(R.layout.dialog_dialogfragment_layout, null);
getDialog().setTitle("Title");
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
DisplayMetrics metrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
getDialog().getWindow().setGravity(Gravity.BOTTOM);
getDialog().getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, (int) (metrics.heightPixels * 0.30));// here i have fragment height 30% of window's height you can set it as per your requirement
getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
getDialog().getWindow().getAttributes().windowAnimations = R.style.DialogAnimationUpDown;
}
and when you want to open,open Bottomsheet dialog like this way :
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.bot_frag, container, false);
TextView tv = v.findViewById(R.id.textVi);
back=v.findViewById(R.id.back_of_bot);
back.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
FragmentManager fm = getFragmentManager();
DialogFragments dialogFragment = new DialogFragments(this);
dialogFragment.show(fm, "Bottomsheet Fragment");
}
}
);
return v;
}
You have to apply this style to you BottomSheetDialogFragment
android.R.style.Theme_Material_Light_NoActionBar_Fullscreen

communicate from dialog fragment to fragment

I have two fragments:AllItemsFragment, CreateItemDialogFragment
The AllItemsFragment displays a list of items in the sqlite,CreateItemDialogFragment is used to create the item to the SQLite.
Now I have a question is after I creating a item in createItemDialogFragment,the dialog dismiss, how to update the display of the items in AllItemsFragment
In AllItemsFragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.d(LIFETAG, "onCreateView");
View view = inflater.inflate(R.layout.fragment_all_items, container, false);
ButterKnife.bind(this, view);
tvTitle.setText("All Items");
DbHandler dbHandler = new DbHandler(getActivity(),null,null,1);
ArrayList<Item> items = dbHandler.getAllItems();
AllItemsAdapter adapter = new AllItemsAdapter(getActivity(),items);
lvItems.setAdapter(adapter);
return view;
}
In CreateItemDialogFragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);
View view =inflater.inflate(R.layout.fragment_create_item_dialog,null);
ButterKnife.bind(this, view);
itemPrice.setInputType(EditorInfo.TYPE_CLASS_NUMBER);
return view;
}
#OnClick(R.id.clear)
void clearDialog(){
dismiss();
}
//create item
#OnClick(R.id.save)
void saveItem() {
if(!itemName.getText().equals(null)||!itemPrice.getText().equals(null)){
String name = itemName.getText().toString();
String priceStr = itemPrice.getText().toString();
Double price = Double.parseDouble(priceStr);
Item item = new Item(name,price);
DbHandler dbHandler = new DbHandler(getActivity(),null,null,1);
dbHandler.addItems(item);
dismiss();
}
}
Try to update the data on onResume callback of the AllItemsFragment.
#Override
public void onResume(){
super.onResume();
// update data over here.
}

Detecting the right View

I need a little bit help, defining my in event_filter.xml declared Views.
It is an child of an AbstractDetailListFragment and implements a DatePicker and a Spinner item.
But I dont know how to acces them in an AbstractDetailFragment.
By defining
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View theView = super.onCreateView(inflater, container, savedInstanceState);
ImageButton searchEnterButton = (ImageButton)getNavigationFragment().getNavigationBar().getRightButton();
View view = getView();
final DatePicker datePicker = (DatePicker) container.findViewById(R.id.datePickerEvent);
Spinner inSpinner = (Spinner) container.findViewById(R.id.category_list);
spinner = inSpinner;
downloadCategories();
the variables view, datePicker, inSpinner always are null!
Any Ideas?
thanks a lot.
That's a thing about fragments. I've been looking for the same error for days, until I read a little bit about fragments (i was lazy and i recommend you not to follow my footsteps ). The way i solved it was by overriding onViewCreated and "catching" views there:
public class MyFragment extends Fragment {
View rootView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.my_fragment, container,
false);
return rootView;
}
//and you use rootView to call findViewById
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Button myButton = (Button) rootView.findViewById(R.id.mybutton);
sendFeedback.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//do something
}
});
}
}

Maintain fragment's view state

I have seen Link1 for this issue but could understand it right. I have a fragment that loads a list. When i click the list item it opens another activity. But i press back button it loads the list again. I want it to be at the same scroll position where it was before. In above mentioned link it specifies to use flag but i haven't got the point.
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dashboard);
android.app.Fragment fragment = new MeFragment();
getFragmentManager().beginTransaction().replace(R.id.layout_FragmentsContainer, fragment).addToBackStack(null).commit();
}
}
public class MeFragment extends Fragment
{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.fragment_me, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
meLV = (ListView) getView().findViewById(R.id.lv_Inbox);
loadingListProgress = (ProgressBar) getView().findViewById(R.id.progress_LoadingList);
meList = new ArrayList<Message>();
meAdapter = new MessagesListAdapter(getActivity(), meList);
//addFooter();
meLV.setAdapter(meAdapter);
meLV.setOnItemClickListener(this);
pageCount = 0;
loadmoreProgressDialog = new ProgressDialog(getActivity());
loadmoreProgressDialog.setTitle("Please wait ...");
loadmoreProgressDialog.setMessage("Loading more ...");
loadmoreProgressDialog.setCancelable(true);
loadUserMessages();
meLV.setOnScrollListener(new EndlessScrollListener() {
#Override
public void onLoadMore(int page, int totalItemsCount) {
// TODO Auto-generated method stub
//addFooter();
loadmoreProgressDialog.show();
loadUserMessages();
}
});
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// TODO Auto-generated method stub
Utils.showToast_msg(getActivity(), "MessageItemClicked");
ReferralDetailFragment fragment = new ReferralDetailFragment();
getFragmentManager().beginTransaction().replace(R.id.layout_FragmentsContainer, fragment).addToBackStack(null).commit();
}
}
public class ReferralDetailFragment extends Fragment implements OnClickListener {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_referraldetail,container, false);
linkToAcknowledge = (TextView) view.findViewById(R.id.lbl_Link_to_Acknowledge);
return view;
}
}
I implemented a simple solution for this in my app, basically when you press back to go to the fragment again, onCreateView() is called. Here in onCreateView() you have done all initialization, so we change
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_me, container, false);
/*
*Whatever you want to do
*
*/
return view;
}
to:
View view;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
if(view==null){
view = inflater.inflate(R.layout.fragment_me, container, false);
/*
*Whatever you want to do
*
*/
}
else{
((ViewGroup)view.getParent()).removeView(view);
}
return view;
}
Here, we move View view outside and make it a class variable. So if it is the first time the fragment is called, it is null and the initialization occurs, otherwise it goes to else black. Else block is required because onCreateView() adds whatever it returns as a child of the view's parent, so since view is already there, we remove it and onCreateView automatically adds it again.
According to our exchange in the comments, I completely deletde my answer and re-write a new one.
I copy/paste the code from one of my apps and removing the useless things and changing the names. Hope there is not too many typing mistakes, at that it is the minimum required to have it working.
When I pop back to FirstFragment from SecondFragment, the scroll position of FirstFragment is the same as when I clicked an item to load the SecondFragment.
Note that I don't extend FragmentActivity. I have an activity which loads the fragments.
Extend/modify to match your needs.
MainActivity :
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_layout);
}
}
FirstFragment Class :
public class FirstFragment extends Fragment implements OnItemClickListener {
private ListView mListView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.first_fragment_layout, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mListView = (ListView) getView().findViewById(R.id.listview_first_fragment);
mListView.setAdapter(mAdapter); // depends on your adapter
mListView.setOnItemClickListener(this);
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mListView.setItemChecked(position, true);
//in case you need, set the bundle here, for example pass the position
Bundle arguments = new Bundle();
arguments.putInt("position", position);
SecondFragment secondFragment = new SecondFragment();
secondFragment.setArguments(arguments);
getFragmentManager().beginTransaction().replace(R.id.fragment_container, secondFragment).addToBackStack(null).commit();
}
}
SecondFragment Class :
public class SecondFragment extends Fragment {
private Integer mPosition;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.second_fragment_layout, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Bundle arguments = getArguments();
if (arguments == null) {
mPosition= 0;
} else {
mPosition= arguments.getInt("Position");
}
}
}
What you are trying to achieve may be done with help of savedInstanceState. i also had this kind of problem which i resolved by using add() method instead of replace() in transition.
If you can change your method or already not using add() than give it a shot.
and if add() method didn't do the trick then check the implementation of savedInstanceState.
correctly save instance state.
How to save states of fragment views.

Categories

Resources