i have an ActionBar that has 2 tabs and each tabs layout is a fragment. in 1 of these tabs , there is a listView. and i want to set ArrayAdapetr for it. but when i run app, error occurred and error is about my application context. my code is :
public class TarfandFrag extends Fragment {
String values[] = new String[]{"sadeq","ali"};
ListView listView;
Context context;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.tarfad_layout,container,false);
listView = (ListView) view.findViewById(R.id.list_tarfand);
return view;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ArrayAdapter adapter = new ArrayAdapter(context,android.R.layout.simple_list_item_1,values);
listView.setAdapter(adapter);
}
}
but its not working. notice that i don't want use listFragment or anything else. i replace context with getActivity() , context.getApplicationContext, getActivity.getApplicationContext. but not working. plz help meeeee
Assing getActivity() to context in onCreate.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context=getActivity();
}
In a fragment, onCreate() is called before onCreateView(). the consequence of this is that, at the point onCreate() is called, your ListView is not yet associated with an element in the layout (as your are doing this in onCreateView() which gets called later) and will hence resolve to null and you will get a null pointer exception when you set the adapter for the ListView. Move the code setting the adapter to within the onCreateView() method and use getActivity() and you should be fine.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.tarfad_layout,container,false);
listView = (ListView) view.findViewById(R.id.list_tarfand);
// Here listview will not be null as it is now bound to an object
ArrayAdapter adapter = new ArrayAdapter(getActivity(),android.R.layout.simple_list_item_1,values);
listView.setAdapter(adapter);
return view;
}
Related
I'm new to fragments and they are a bit confusing to me right now.
I have read alot and actually built a test app using this tutorial
I was able to add more tabs and so on. But I don't want to display static
content (xmls). I want to be able to modify the UI add listviews, load json data with asynctasck and so on but the very first attempt I made has failed.
So on Tab1:
public class Tab1 extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v =inflater.inflate(R.layout.tab_1,container,false);
return v;
}
}
I tried to declare a textview and edit it's text with settext but
I get a crash and also findviewbyid is not available as a method.
It didn't throw and error when I typed getView().findViewById but
that's not the problem.
Are fragments limited or very different from traditional activities?
Do I need to make never ending customizations
in order to get a listview loading?
Thank you.
You should declare your TextView as a Member variable for your class and get a reference to that view in onCreateView like:
public class Tab1 extends Fragment {
// your TextView member variable
private TextView mTextView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, #Nullable Bundle savedInstanceState) {
View v =inflater.inflate(R.layout.tab_1, container, false);
mTextView = (TextView) v.findViewById(R.id.my_text_view);
return v;
}
// It is safe to access the views here, not in onCreate since it is called before onCreateView
#Override
public void onActivityCreated(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
mTextView.setText("Hello, World!");
}
}
For reference on the Fragment lifecycle
Are fragments limited or very different from traditional activities?
A Fragment has its own lifecycle like that of an Activity but it is dependent upon the lifecycle of its parent Activity, so to answer your question they are not very different, it is just a good practice for modularizing code.
Do I need to make never ending customizations in order to get a listview loading?
A little unclear what you mean by never ending customizations but loading a dynamic ListView is very simple in Android.
For Example:
using fragment_one.xml we have just a FrameLayout
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fl_list_container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
And the code:
public class Tab1 extends Fragment {
// your FrameLayout member variable
private FrameLayout mFlParent;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_one, container, false);
mFlParent = (FrameLayout) v.findViewById(R.id.fl_list_container);
return v;
}
// It is safe to access the views here, not in onCreate since it is called before onCreateView
#Override
public void onActivityCreated(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
// Create a new list, adapter and add a item click listener
ListView myList = new ListView(context); // context needed
myList.setAdapter(new ArrayAdapter<String>(context, android.R.id.simple_list_item_1, new String []{"Item 1", "Item 2", "Item 3", "Item 4"}));
myList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//... handle clicks on list items as usual
}
});
// add the view to the FrameLayout
mFlParent.addView(myList); // may want to call mFlParent.removeAllViews(); before adding just to be safe
}
}
Good luck and happy coding.
Fragment doesn't have an activity methods.
If you want to use findViewById methods, you should use a class field.
public class Tab1 extends Fragment {
private View mView;
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
mView = inflater.inflate(R.layout.tab_1,container,false);
return mView;
}
#Override
public void onCreate() {
// here you can use `findViewById` method via `mView` variable
mView.findViewById(YOUR_VIEW_ID);
}
}
There is basically 2 method to be use in fragment
1. onCreateView
2. onViewCreated
First one is use to inflate layout on your fragment
Second one is use to find all view used in your layout.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, #Nullable Bundle savedInstanceState) {
View v =inflater.inflate(R.layout.tab_1, container, false);
return v;
}
#Override
public void onViewCreated(View v){
mTextView = (TextView) v.findViewById(R.id.my_text_view);
mTextView.setText("Hello, World!");
}
I have a MainActivity with a ViewPager. The ViewPager consists of two Fragments each holding a single RecyclerView. I need to have a reference to the RecyclerView for updating/animating it etc. in the Fragment.
A problem occurs on screen rotation, because for some reason I cannot set the member variable back to the RecyclerView.
public abstract class NotifListFragment extends Fragment {
protected RecyclerView mRecyclerView;
public NotifListFragment() {
// Required empty public constructor
EventBusHelper.getBus().register(this);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
mRecyclerView = (RecyclerView) inflater.inflate(R.layout.fragment_notif_list, container, false);
setupRecyclerView(mRecyclerView);
return mRecyclerView;
}
So here in the onCreateView I always inflate the fragment and save the reference in mRecyclerView variable. However, when I later try to access it, it is null.
I am using Otto to call both Fragment's onDataChanged() method. It is called when a button in the RecyclerView is pressed.
#Subscribe
public void onDataChanged(DataChangedEvent event) {
List<CustomNotification> oldData = ((NotifRecyclerViewAdapter) mRecyclerView.getAdapter()).getmValues();
List<CustomNotification> newData = getNotifications();
}
The mRecyclerView.getAdapter() is null in this call.
Fragment's getView() also returns null. What is happening?
There are a few things that I found wrong here. Please don't call setupRecyclerView(mRecyclerView); in your onCreateView(), this is something that should be called on your activityCreated() because your fragment might not have been attached to your activity till then. Plus I don't like to do findViewByIds there.
Use the onViewCreated() and onActivityCreated() callbacks.
So your code would look something like this.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_notif_list, container, false);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mRecycler = (RecyclerView) view.findViewById(R.id.yourId);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
setupRecyclerView(mRecycler);
}
It's possible that during your call to onDataChanged() that the fragment might not have been added. Do a null check there.
My listview gets filled on the start but after i cant find a way to make changes
pls see the code bellow
public class myFragment extends android.support.v4.app.Fragment
{
ListView list;
ArrayList<String> restorants=new ArrayList<String>();
Manager m=new Manager();
ArrayAdapter<String> adapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_, container, false);
list=(ListView) rootView.findViewById(R.id.myList);
for(Restorant r : m.getResByCity("nyc"))
{
restorants.add(r.getName());
}
adapter=new ArrayAdapter<String>(getActivity(), R.layout.item_list, R.id.restorantItem,restorants);
list.setAdapter(adapter);
return rootView;
}
public void makeChange(String s)
{
restorants.remove(0);
((ArrayAdapter)list.getAdapter()).notifyDataSetChanged();
}
}
While calling the method makeChange() i have checked that the restorants items are removing so that there is no problem with calling the method
makeChange() is called from my mainActivity that contains viewpager where this fragment is contained in the viewpager.
you need to remove the element from the dataset you provided to the adapter,
adapter.remove(s)
Here you can find the documentation
I'm trying to implement a simple to do list using this solution Add user input into a ListView on button click, but when I implement the onCreate of the solution I get the following errors http://pastebin.com/9CBCMrjv I'm using fragments in this application and I'm wondering could this be causing the errors as maybe the constructors don't apply to fragments.
Can someone make sense of the errors or where I'm going wrong with this implementation? My understanding of the errors is that this solution can't be applied to my class as it is linked to a fragment instead of a plain activity.
This is the complete class to give you a better understanding of the problem:
public class TopRatedFragment extends Fragment implements OnClickListener {
ListView mListView;
EditText mValue;
Button mAdd;
ArrayList<String> list = new ArrayList<String>();
ArrayAdapter<String> adapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_top_rated, container, false);
return rootView;
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_top_rated);
mAdd = (Button)findViewById(R.id.newList);
mAdd.setOnClickListener(this);
mValue = (EditText)findViewById(R.id.listData);
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, list);
// set the lv variable to your list in the xml
mListView=(ListView)findViewById(R.id.listView);
mListView.setAdapter(adapter);
}
public void onClick(View v)
{
String input = mValue.getText().toString();
if(input.length() > 0)
{
// add string to the adapter, not the listview
adapter.add(input);
// no need to call adapter.notifyDataSetChanged(); as it is done by the adapter.add() method
}
}
}
The errors
The method setContentView(int) is undefined for the type TopRatedFragment
The method findViewById(int) is undefined for the type TopRatedFragment
The method setOnClickListener(View.OnClickListener) in the type View is not applicable for the arguments (TopRatedFragment)
The method findViewById(int) is undefined for the type TopRatedFragment
The constructor ArrayAdapter<String>(TopRatedFragment, int, ArrayList<String>) is undefined
The method findViewById(int) is undefined for the type TopRatedFragment
setContentView(R.layout.fragment_top_rated);
wrong
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_top_rated, container, false);
mAdd = (Button)rootView.findViewById(R.id.newList);
mAdd.setOnClickListener(this);
mValue = (EditText)rootView.findViewById(R.id.listData);
adapter = new ArrayAdapter<String>(getActivity, android.R.layout.simple_expandable_list_item_1, list);
// set the lv variable to your list in the xml
mListView=(ListView)rootView.findViewById(R.id.listView);
mListView.setAdapter(adapter);
return rootView;
}
You need to inflate a view in onCreateView and return the view
Also you use the inflated view object to initialize your views
The constructor ArrayAdapter<String>(TopRatedFragment, int, ArrayList<String>) is undefined
So change to
adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_expandable_list_item_1, list);
get rid of the codes in onCreate
I want a custom row, so I am using a List View in an xml and inflating into a fragment. I am very confused of how to set the adapter for the list View.
I created a new adapter which extends Base Adapter. In the getView method, I really don't know what context to pass while inflating the row.xml layout.
How do I set the adapter for the list view and where?
public class ResultsFragment extends Fragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.results_layout, container, false);
listView = (ListView)v.findViewById(R.id.results);
return v;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
loadPage(dataBean.getWhat(), dataBean.getWhere(), dataBean.getPageStart());
//resultsAdapter.setRssData(rssData);
//setListAdapter(resultsAdapter);
}
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
Context context = getActivity().getApplicationContext();
resultsAdapter = new ResultsAdapter(context);
}
/**
* Set List Adapter
*/
private void setAdapter(){
if(listView.getAdapter() == null){
listView.setAdapter(resultsAdapter);
}
else{
resultsAdapter.notifyDataSetChanged();
}
}
}
You must extend Listfragment (instead of Fragment), and using its ListFragment.setListAdapter to set your adapter. In the adapter getView() inflate your row.. that s all
If you do not want to change your extended class, you should use listview.setAdapter(...) method. As you see in my example :
ListView productList= (ListView) getActivity().findViewById(R.id.product_list);
SampleAdapter adapter = new SampleAdapter(getActivity());
adapter.add(new SampleItem(
"Sunny LCD TV 2\" SN022L66-T1 Full HD",
R.drawable.product_sample_pic);
productList.setAdapter(adapter);