I have a problem when try to add setOnItemClickListener into a Fragment.
This is my Fragment.
public class LocalesFragmento extends Fragment {
ListView locales_list;
private List localesList;
private Context context;
public LocalesFragmento() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View vista = inflater.inflate(R.layout.locales_list, container, false);
locales_list = (ListView) vista.findViewById(R.id.localesList);
new getLocalesAsyncTask().execute();
return vista;
}
private void setListAdapter() {
Log.e("Adapter","Adapter...");
locales_list.setAdapter(new LocalesAdapter(getActivity(), getActivity(), localesList));
locales_list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
//detailInstagram(list.get(position));
}
});
}
The setOnItemClickListener is never executed. Any ideas?
Do I need to implement some other method?
Thanks.
Best regards.
You start your AsyncTask on onActivityCreated method because here before attaching the layout you are starting an async and that may be the reason why the listener is setting up.
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
locales_list.setAdapter(new LocalesAdapter(getActivity(), getActivity(), localesList));
locales_list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
//detailInstagram(list.get(position));
}
});
new getLocalesAsyncTask().execute();
}
Your LocalesAdapter might be the cause. You are passing the context (getActivity()) to the adapter twice.
locales_list.setAdapter(new LocalesAdapter(getActivity(), getActivity(), localesList));
Make your that the arguments passed to the LocalesAdapter are correct.
Related
I have a widget, which opens a Fragment showing a list of contacts with their pictures. This Fragment consumes a lot of memory. On leaving the Fragment, the memory is still allocated...
public class ListFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
final List<BWContact> contacts = ContactHandler.getByGroup(group);
final ListView listView = (ListView) this.getActivity().findViewById(R.id.contact_list);
listView.setAdapter(new BWContactAdapter(getActivity(), contacts, true));
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
...
}
});
return null;
}
#Override
public void onDestroyView() {
super.onDestroyView();
}
}
How can I tell the fragment to free the memory?
I don't understand this line:
final ListView listView = (ListView) this.getActivity().findViewById(R.id.contact_list);
Is your list attached to the activity? In this case, yes the activity will retain the listView with all the contacts.
I have a main activity which consists of spinner + 3 fragments (tabs). I want to access spinner value from fragment. So I wrote this code into onActivityCreated inside my fragment:
final Spinner spinner = (Spinner) getView().findViewById(R.id.spinnerOblasti);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
/*TextView[] vystrahy = new TextView[1];
vystrahy[0] = (TextView) getView().findViewById(R.id.txtVystrahy);
(new htmlParser(vystrahy, 0) ).execute(new Integer[]{spinner.getSelectedItemPosition()});*/
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
but when I run my application spinner throws nullpointerexception. Any ideas on how to access it from fragment?
Here is my onCreateView which I believe is causing problem but I dont know how to fix it:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_tab1, container, false);
return rootView;
}
Thanks in forward
Doesn't work like that, what do you mean for spinner value? If you want to access to the spinner object you have to setup an interface which will be implemented by your activity and then in onActivityCreated you can call the method of that interface to do something. For example:
public class MyClass implements MyInterface {
public interface MyInterface {
void doSomethingWithSpinner();
}
public void doSomethingWithSpinner() {
mySpinner.setVisibility(View.VISIBLE);
}
}
And your onActivityCreated:
if(getActivity() instanceof MyInterface) {
((MyInterface)getActivity()).doSomethingWithSpinner();
}
I developed an app which fills a list. It works fine in the way I did it but I'm not conviced that I solved the problem in a recommended way. I read that you should override onActivityCreated in a Fragment and fill the list there instead of doing this in onCreateView. onCreateView should only be used to inflate static views. Is this true? If yes, how should these two methods look like in the end?
This is my Fragment class:
public class FragmentMain extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main, container, false);
List<MyItem> items = createListItems();
ListView listView = (ListView) view.findViewById(R.id.list);
MyListAdapter adapter = new MyListAdapter(view.getContext(), items);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Toast.makeText(view.getContext(),
"Clicked " + position, Toast.LENGTH_LONG)
.show();
}
});
return view;
}
.
.
.
}
My MainActivity just adds the fragment:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentMain fm = new FragmentMain();
getFragmentManager().beginTransaction()
.add(R.id.fragment_main_container, fm).commit();
}
.
.
.
}
That is true to a certain extend only because onCreateView happens on the UI thread and you don't want anything slowing that down otherwise your UI will be slow and choppy. For example, in your fragment class you have a call to a method "createListItems()". I don't know how many items you're making but if it's a lot it could slow down your UI (especially if youre accessing a database and querying objects and so on). So you could do it in onActivityCreated but you could also use an AsyncTask. So your code would become something like this:
public class LoadListObjectsTask extend AsyncTask<Void, List<MyItem>, Void> {
private MyListAdapter myListAdapter;
private Context mContext;
public LoadListObjectsTask(Context context) {
this.mContext = context;
}
#Override
public void doInBackground(Void...params) {
//create your list objects here instead of on UI thread. This will run on a separate thread.
myListAdapter = new MyListAdapter(mContext, items);
return items; //return list of MyItems
}
//This is called when doInBackground is done. THIS WILL RUN ON THE UI THREAD So don't do
//anything slow here
#Override
public void onPostExecute(List<MyItem>...params //don't really need the list here//) {
listView.setAdapter(myListAdapter);
}
}
then in your fragment
public class FragmentMain extends Fragment {
private ListView listView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main, container, false);
List<MyItem> items = new ArrayList<MyItem>();
listView = (ListView) view.findViewById(R.id.list);
//new code
new LoadListObjectsTask(getActivity()).execute();
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Toast.makeText(view.getContext(),
"Clicked " + position, Toast.LENGTH_LONG)
.show();
}
});
return view;
}
public void onResume()... {
//also add the task here so your content is reloaded on resume..
new LoadListObjectsTask(getActivity()).execute();
}
.
.
.
}
If you don't want to do this just make your List of MyItems a private field and move
List<MyItem> items = createListItems();
to onActivityCreated().
Hope that helps!
I am using import android.support.v4.app.ListFragment to create a ListFragment. Inside the fragment itself -- not the parent activity -- I want to implement the onItemClick method. Will someone please provide a simple example on how this might work?
public class MyListFragment extends ListFragment {
Spannable[] stuff = {};//to be filled
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ArrayAdapter<Spannable> adapter = new ArrayAdapter<Spannable>(inflater.getContext(), android.R.layout.simple_list_item_1, stuff);
setListAdapter(adapter);
return super.onCreateView(inflater, container, savedInstanceState);
}
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
//this is red underlined by eclipse
}
}
Have you done some research before asking that? Anyway, it can be done by overriding onListItemClick method, as following:
public class Test extends ListFragment {
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
//do the stuff
}
}
I can not get setOnItemClickListener of gridView in Fragment. What can be the problem?
Here is my code::
public class MainMenuFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.main_menu_fragment, container, false);
itemsGridViewObj = (GridView) view.findViewById(R.id.itemsGridView);
itemsGridViewObj.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long arg3) {
Log.d(TAG, "--> onItemClick listener..."); // Can not getting this method.
/*if(position == 1) {
FruitMenuFragment fruitMenuFragment = new FruitMenuFragment();
fragmentTransaction.replace(android.R.id.content, fruitMenuFragment);
fragmentTransaction.commit();
}*/
}
});
return view;
}
}`
You may need to set the following in your ButtonView.
android:focusable="false"
android:focusableInTouchMode="false"
see adding CheckBox to list row loses my onItemClick events?
When using Fragments the initialisation of the view occurs over two stages.
The view is only inflated (and therefore accessible) after the onCreateView method. This method is only for inflating a view and returning it to the Fragment.
Therefore, any logic to do with finding views and setting up onClickListeners should be done in the onActivityCreated() function as this is the first point at which you can access the inflated view.
Have a look at the Google docs at http://developer.android.com/reference/android/app/Fragment.html#Lifecycle
Below is you code adjusted to comply to what I have described above:
public class MainMenuFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.main_menu_fragment, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
GridView itemsGridViewObj = (GridView) findViewById(R.id.itemsGridView);
itemsGridViewObj.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long arg3) {
Log.d(TAG, "--> onItemClick listener..."); // You should see this now
/*if(position == 1) {
FruitMenuFragment fruitMenuFragment = new FruitMenuFragment();
fragmentTransaction.replace(android.R.id.content, fruitMenuFragment);
fragmentTransaction.commit();
}*/
}});
}
}