Create listview in fragment android - android

As the title I want to create a listview with custom row in Fragment. My code below.
Fragment class
public class PhotosFragment extends Fragment{
public PhotosFragment(){}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_photos, container, false);
ArrayList<ListviewContactItem> listContact = GetlistContact();
ListView lv = (ListView)getActivity().findViewById(R.id.lv_contact);
lv.setAdapter(new ListviewContactAdapter(getActivity(), listContact));
return rootView;
}
private ArrayList<ListviewContactItem> GetlistContact(){
ArrayList<ListviewContactItem> contactlist = new ArrayList<ListviewContactItem>();
ListviewContactItem contact = new ListviewContactItem();
contact.SetName("Topher");
contact.SetPhone("01213113568");
contactlist.add(contact);
contact = new ListviewContactItem();
contact.SetName("Jean");
contact.SetPhone("01213869102");
contactlist.add(contact);
contact = new ListviewContactItem();
contact.SetName("Andrew");
contact.SetPhone("01213123985");
contactlist.add(contact);
return contactlist;
}
}
Adapter class
public class ListviewContactAdapter extends BaseAdapter{
private static ArrayList<ListviewContactItem> listContact;
private LayoutInflater mInflater;
public ListviewContactAdapter(Context photosFragment, ArrayList<ListviewContactItem> results){
listContact = results;
mInflater = LayoutInflater.from(photosFragment);
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return listContact.size();
}
#Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return listContact.get(arg0);
}
#Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return arg0;
}
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder holder;
if(convertView == null){
convertView = mInflater.inflate(R.layout.contact_item, null);
holder = new ViewHolder();
holder.txtname = (TextView) convertView.findViewById(R.id.lv_contact_item_name);
holder.txtphone = (TextView) convertView.findViewById(R.id.lv_contact_item_phone);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.txtname.setText(listContact.get(position).GetName());
holder.txtphone.setText(listContact.get(position).GetPhone());
return convertView;
}
static class ViewHolder{
TextView txtname, txtphone;
}
}
But when I run the app that display no thing. Could anyone tell me what wrong here and how can I fix it?

I guess your app crashes because of NullPointerException.
Change this
ListView lv = (ListView)getActivity().findViewById(R.id.lv_contact);
to
ListView lv = (ListView)rootView.findViewById(R.id.lv_contact);
assuming listview belongs to the fragment layout.
The rest of the code looks alright
Edit:
Well since you said it is not working i tried it myself

Please use ListFragment. Otherwise, it won't work.
EDIT 1:
Then you'll only need setListAdapter() and getListView().

you need to give:
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
}
inside fragment.

The inflate() method takes three parameters:
The id of a layout XML file (inside R.layout),
A parent ViewGroup into which the fragment's View is to be inserted,
A third boolean telling whether the fragment's View as inflated from
the layout XML file should be inserted into the parent ViewGroup.
In this case we pass false because the View will be attached to the
parent ViewGroup elsewhere, by some of the Android code we call (in
other words, behind our backs). When you pass false as last parameter
to inflate(), the parent ViewGroup is still used for layout
calculations of the inflated View, so you cannot pass null as parent
ViewGroup .
View rootView = inflater.inflate(R.layout.fragment_photos, container, false);
So, You need to call rootView in here
ListView lv = (ListView)rootView.findViewById(R.id.lv_contact);

Instead:
public class PhotosFragment extends Fragment
You can use:
public class PhotosFragment extends ListFragment
It change the methods
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ArrayList<ListviewContactItem> listContact = GetlistContact();
setAdapter(new ListviewContactAdapter(getActivity(), listContact));
}
onActivityCreated is void and you didn't need to return a view like in onCreateView
You can see an example here

Related

i have an error at setText in adapter class

public class AdapterListView extends BaseAdapter {
Context context;
ArrayList<String> brands;
public AdapterListView(ArrayList<String> brands, Context context) {
this.brands = brands;
this.context = context;
}
#Override
public int getCount() {
return brands.size();
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
view= LayoutInflater.from(context).inflate(R.layout.activity_listview,null);
ListView lv=(ListView)view.findViewById(R.id.mobile_list);
lv.setText(brands.get(i));
return view;
}
}
setText has error and displaying (cannot resolve method,settext(java.lag.string))
my message fragment class is given bellow am actually trying to set a listview
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_messages, container, false);
brands.add("microsoft");
brands.add("ios" );
brands.add("android");
AdapterListView adapter = new AdapterListView(brands,getActivity());
ListView listView = (ListView)rootView.findViewById(R.id.mobile_list);
listView.setAdapter(adapter);
// Inflate the layout for this fragment
return rootView;
}
i need to print the list brands.is thr any error in the way i set the listview
setText has error and displaying (cannot resolve
method,settext(java.lag.string))
Because setText method is not defined in ListView class.
Use TextView,EditText,Button like views for using setText method
instead of
ListView lv=(ListView)view.findViewById(R.id.mobile_list);
lv.setText(brands.get(i));
you have to take TextView in your R.layout.activity_listview
and than code should be
TextView tv=(TextView)view.findViewById(R.id.textViewId);
tv.setText(brands.get(i));

Converting Intent to Fragment in Android

In general most of the time I work with Intent rather than Fragment because I found It somehow complex. I have a class with ListView to show some data from an array and I want to convert it in Fragment also want to pass the extras in a new fragmented class.
ListView Class:
public class MainActivity extends Activity {
ListView list;
String[] web = { "Google", "Twitter", "Windows", "Bing", "Itunes",
"Wordpress", "Drupal" };
Integer[] imageId = { R.drawable.ic_launcher, R.drawable.ic_launcher,
R.drawable.ic_launcher, R.drawable.ic_launcher,
R.drawable.ic_launcher, R.drawable.ic_launcher,
R.drawable.ic_launcher
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
CustomList adapter = new CustomList(MainActivity.this, web, imageId);
list = (ListView) findViewById(R.id.list);
list.setAdapter(adapter);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Toast.makeText(MainActivity.this,
"You Clicked at " + web[+position], Toast.LENGTH_SHORT)
.show();
Intent i = new Intent(MainActivity.this, intent.class);
i.putExtra("name", web[+position]);
startActivity(i);
}
});
}
}
CustomList Class:
public class CustomList extends ArrayAdapter<String> {
private final Activity context;
private final String[] web;
private final Integer[] imageId;
public CustomList(Activity context, String[] web, Integer[] imageId) {
super(context, R.layout.list_single, web);
this.context = context;
this.web = web;
this.imageId = imageId;
}
#Override
public View getView(int position, View view, ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View rowView = inflater.inflate(R.layout.list_single, null, true);
TextView txtTitle = (TextView) rowView.findViewById(R.id.txt);
ImageView imageView = (ImageView) rowView.findViewById(R.id.img);
txtTitle.setText(web[position]);
imageView.setImageResource(imageId[position]);
return rowView;
}
}
I got a main class with three tabs created using fragment and in this class I would like to add the ListView!
public class LayoutOne extends Fragment {
public static Fragment newInstance(Context context) {
LayoutOne f = new LayoutOne();
return f;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
ViewGroup root = (ViewGroup) inflater.inflate(R.layout.layout_one, null);
return root;
}
#Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
}
}
What I want to do is to show the listview in the fragment class and when a list item will be click I want to launch the New Intent to show which Item was clicked!
If you want to pass parameters into a Fragment, common practice is to create a static method that produces an instance of your Fragment with certain parameters. You already have the newInstance method, now you just need to add parameters to the arguments and return the Fragment. You should check for the arguments in your onCreateView The following is an example of how you would write one.
public class LayoutOne extends Fragment
{
public static Fragment newInstance(int someInt, String someString)
{
LayoutOne f = new LayoutOne();
Bundle args = new Bundle();
args.putInt("someInt", someInt);
args.putString("someString", someString);
f.setArguments(args);
return f;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)
{
ViewGroup root = (ViewGroup) inflater.inflate(R.layout.layout_one, null);
Bundle args = getArguments();
//From here you would check to see if your arguments are present
//proceed accordingly
return root;
}
}
For your specific case, you could pass along the String array and add it as an argument.
Hope this helps. Good luck!
Edit
The problem you're facing is that you're instantiating a ListView in your Activity when in reality you should be doing it in your Fragment. Intents aren't needed here, you just need to make sure that there is a ListView attribute to get from the layout you attach to your Fragment. The following is a small example of how that should work.
Note, this method goes in your LayoutOne class
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)
{
ViewGroup root = (ViewGroup) inflater.inflate(R.layout.layout_one, null);
//Be sure to use the actual id of your list view
ListView lv = (ListView) root.findViewById(R.id.list_view_id);
//Make sure that you retrieve the values for 'web' and 'imageId' from
//the activity using the "newInstance" method.
CustomList adapter = new CustomList(getActivity(), web, imageId);
lv.setAdapter(adapter);
//From here, set your onClickListener and stuff as you did in your Activity
return root;
}
As a note, Fragments don't have the findViewById method. You have to call it on the View that you are inflating to be its layout, so in this case you inflated root and then you would call root.findViewById(R.id.some_id) to get a view.

Exception in ListFragment: The specified child already has a parent

I'm making a downloader app, and i got child's parents error after the onCreateView return section.
I tried a lots of things, but nothing help. I tried:
((ViewGroup)dlistView.getParent()).removeView(dlistView);
after that the compiler says:
01-12 12:05:15.558: E/AndroidRuntime(10740): java.lang.RuntimeException: Your content must have a ListView whose id attribute is 'android.R.id.list'
or remove the container/ i got an npe/ or remove the V but the V.getParent() is null.
Which view is the parent, and which is the child?
The code:
public static class DownloadingFragment extends ListFragment {
public static final String ARG_SECTION_NUMBER = "section_number";
public DownloadingFragment() {
}
#Override
public View onCreateView (LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View V = inflater.inflate (R.layout.list, null);
ListView dlistView = (ListView) V.findViewById(R.id.dlist);
List<DownloadInfo> downloadInfo = new ArrayList<DownloadInfo>();
downloadInfo.add(new DownloadInfo("File", 1000));
DownloadInfoArrayAdapter diaa = new DownloadInfoArrayAdapter(
getActivity().getApplication(),R.layout.list, downloadInfo);
dlistView.setAdapter(diaa);
return dlistView; // throw exception
}
}
//...
}
Thank you in advance for your help.
EDIT:
the new code:
public static class DownloadingFragment extends Fragment {
public static final String ARG_SECTION_NUMBER = "section_number";
public DownloadingFragment() {
}
#Override
public View onCreateView (LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View V = inflater.inflate (R.layout.list, null);
return V;
}
#Override
public void onStart() {
// TODO Auto-generated method stub
super.onStart();
ListView dlistView = (ListView) getView().findViewById(R.id.dlist);
List<DownloadInfo> downloadInfo = new ArrayList<DownloadInfo>();
downloadInfo.add(new DownloadInfo("File", 1000));
DownloadInfoArrayAdapter diaa = new DownloadInfoArrayAdapter(
getActivity().getApplication(),R.layout.list, downloadInfo);
dlistView.setAdapter(diaa);
}
}
//...
}
that's because you return the listview which has a parent (somewhere in V's layout tree) .
for any type of fragment , onCreateView should return a view that doesn't have any parent .
in this case , since it's a listFragment , create the listview (either using xml or programmatically ) , and then return it . do not allow it to have any parents since it needs to have a parent as a fragment .
read here for more information :
The system calls this when it's time for the fragment to draw its
user interface for the first time. To draw a UI for your fragment, you
must return a View from this method that is the root of your
fragment's layout. You can return null if the fragment does not
provide a UI.
Note that the third argument of inflate is false.
so replace this line
View V = inflater.inflate (R.layout.list, null);
with this
View V = inflater.inflate (R.layout.list, null,false);
and you are done.hope this helps.

Fragment does not refresh its content

In the following code I have set up a fragment that shows 2 ListViews.
When the main activity call the Fragment methods:
prendiListaBest
and
prendiListaWorst
they call notifyDataSetChanged() on the adapters,
therefore the lists should update with the new contents of the ArrayLists.
But this does not happen.
Please any help and suggestion more than welcome
public class WorstBest extends Fragment {
public ListView lvBest;
public ListView lvWorst;
public MyAdapter myAdap;
public MyAdapter myAdap2;
public ArrayList<Stock> best;
public ArrayList<Stock> worst;
public View v;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
v= inflater.inflate(R.layout.listaworstbest, container, false);
lvBest= (ListView)v.findViewById(R.id.listbest);
lvWorst=(ListView)v.findViewById(R.id.listworst);;
myAdap= new MyAdapter(best, getActivity());
myAdap2= new MyAdapter(worst, getActivity());
lvBest.setAdapter(myAdap);
lvWorst.setAdapter(myAdap2);
return v;
}
public void prendiListaBest(ArrayList<Stock> al){
Log.e("", "passo per prendilitsa del fragment worstbest");
best=al;
Log.e("", "nel fragment best è" + Integer.toString(best.size()));
myAdap.notifyDataSetChanged();
}
public void prendiListaWorst(ArrayList<Stock> al){
Log.e("", "passo per prendilitsa del fragment worstbest");
worst=al;
Log.e("", "nel fragment worst è" + Integer.toString(worst.size()));
myAdap2.notifyDataSetChanged();
}
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
}
}
This is the code of my custom adapter.
I posted as requested but I apologize because it is really messy:
public class MyAdapter extends BaseAdapter {
ArrayList<Stock> l;
Activity a;
public MyAdapter(ArrayList<Stock> li, Activity ac) {
// TODO Auto-generated constructor stub
l = li;
a=ac;
}
public View getView(int position, View convertView, ViewGroup parent) {
View row=convertView;
if (row==null) {
LayoutInflater inflater=a.getLayoutInflater();
row=inflater.inflate(R.layout.row, parent, false);
}
TextView tw=(TextView)row.findViewById(R.id.textView1);
String st=l.get(position).simbolo;
String st1=st;
String st2=st;
String st3=st;
String st4=st;
String st5=st;
String st6=st;
String st7=st;
String st8=st;
st8=st;
if(st.length()<=7){st1=st.concat(" ");st2=st1;st3=st1;st4=st1;st5=st1;st6=st1;st7=st1;st8=st1;}
if(st1.length()<=7){st2=st1.concat(" ");st3=st2;st4=st2;st5=st2;st6=st2;st7=st2;st8=st2;}
if(st2.length()<=7){st3=st2.concat(" ");st4=st3;st5=st3;st6=st3;st7=st3;st8=st3;}
if(st3.length()<=7){st4=st3.concat(" ");st5=st4;st6=st4;st7=st4;st8=st4;}
if(st4.length()<=7){st5=st4.concat(" ");st6=st5;st7=st5;st8=st5;}
if(st5.length()<=7){st6=st5.concat(" ");st7=st6;st8=st6;}
if(st6.length()<=7){st7=st6.concat(" ");st8=st7;}
if(st7.length()<=7){st8=st7.concat(" ");}
tw.setText(st8);
String allora=(String) tw.getText();
TextView tw2=(TextView)row.findViewById(R.id.nome);
///aggiungiamo numero minimo caratteri
tw2.setText((l.get(position).nome));
///
TextView tw3=(TextView)row.findViewById(R.id.prezzo);
tw3.setText((l.get(position).prezzo));
TextView tw4=(TextView)row.findViewById(R.id.cambiamento);
tw4.setText((l.get(position).cambiamento).concat(" %"));
try {
double value = Double.parseDouble(l.get(position).cambiamento);
if(value<0)tw4.setTextColor(Color.RED);
if(value>0)tw4.setTextColor(Color.GREEN);
TextView tw5=(TextView)row.findViewById(R.id.freccia);
if(value<0)tw5.setText("▼");
if(value>0)tw5.setText("▲");
if(value<0)tw5.setTextColor(Color.RED);
if(value>0)tw5.setTextColor(Color.GREEN);
} catch (Exception exc) {}
return row;
}
public int getCount() {
// TODO Auto-generated method stub
return l .size();
}
public Object getItem(int position) {
// TODO Auto-generated method stub
return l .get(position);
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
}
EDIT EDIT EDIT EDIT EDIT EDIT EDIT EDIT EDIT EDIT EDIT EDIT EDIT EDIT EDIT EDIT EDIT *EDIT EDIT EDIT EDIT EDIT EDIT EDIT EDIT EDIT EDIT EDIT EDIT EDIT EDIT EDIT EDIT EDIT *
Thank you very much, the answer makes perfectly sense.**
But I do not understand why the same Adapter works fine with the following fragment; I explain:
the following "listafragment" fragment has a similar logic, it uses the
prendiLista
method to retrieve the latest version of the
ListArray lt
exactly the same way it is done in the previous "WorstBest" fragment.
But in this case when
public void prendiLista(ArrayList<Stock> al){
lt=al;
myAdap.notifyDataSetChanged();
}
the view is updated !!!
Please what is the difference??? :-)
IN MY UNDERSTANDING THE CALL TO notifyDataSetChanged() WAS ENOUGH TO UPDATE THE VIEW !!
Thanks a lot anyway! (I will accept answer tomorrow morning).
public class listafragment extends Fragment {
public ListView lv;
public MyAdapter myAdap;
public ArrayList<Stock> lt;
public View v;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v= inflater.inflate(R.layout.lista, container, false);
lv= (ListView) v.findViewById(android.R.id.list);
if(lv==null){Log.e("","nel fragment la lista è nulla");}
if(lv!=null){Log.e("","nel fragment la lista NON è nulla");}
myAdap= new MyAdapter(lt, getActivity());
lv.setAdapter(myAdap);
return v;
}
public void prendiLista(ArrayList<Stock> al){
Log.e("", "passo per prendilitsa del fragment");
lt=al;
if(myAdap==null){Log.e("","nel prendilista del fragment myadapt è nullo");};
myAdap.notifyDataSetChanged();
}
public void addToFavorites(int pos){
Quotes.addToFavorites(pos);
}
#Override
public void onCreate(Bundle savedInstanceState){
lt=Quotes.dammi();
super.onCreate(savedInstanceState);
}
}
therefore the lists should update with the new contents of the ArrayLists.
Unfortunately no. When your app first runs l and best both reference the same data. You have this set up.
Fragment:
best ---\
|
|--- <the initial data>
Adapter: |
l ------/
But after you call best=al, you have:
Fragment:
best ------- <the new data>
Adapter:
l ---------- <the initial data>
So you never update the reference in your Adapter. Either add a new method to your custom Adapter to change l or use l itself since you didn't declare it as private:
public void prendiListaBest(ArrayList<Stock> al){
myAdap.l=al;
myAdap.notifyDataSetChanged();
}

GridView inside a Fragment: getView is never called

I have an Activity with a layout made of two Fragment. One of the fragments layout contains a GridView.
public class PicturesGallery extends FragmentActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gallery_frames);
Fragment galleryFragment = fm.findFragmentById(R.id.gallery_fragment);
if (galleryFragment == null) {
fm.beginTransaction().add(R.id.gallery_fragment, new GalleryFragment()).commit();
}
...
When this fragment is called it instantiates the adapter for the GridView, inflates the GridView and sets the adapter (which has been fed with an ArrayList with 15 items to be displayed).
public class GalleryFragment extends Fragment {
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Initialize the layout Adapter
PicturesGallery pga = (PicturesGallery) getActivity();
mAdapter = new ImageAdapter(pga.getApplication(), pga.mMemoryCache,
galleryDir);
mAdapter.mPictureNames = new ArrayList<String>(pictureNames);
// Inflate the layout and set the adapter
LayoutInflater inflater = (LayoutInflater) getActivity()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
GridView gridView = (GridView) inflater.inflate(R.layout.pictures_gallery_fragment, null);
gridView.setAdapter(mAdapter);
}
....
But when the activity is executed nothing happens (no errors in the logcat but nothing displayed on the GridView). In the adapter class, using Log.d() inside getView() indicates that the method is never called. However getCount() returns the right number of items. The relevant code follows.
public class ImageAdapter extends BaseAdapter {
...
public ArrayList<String> mPictureNames = new ArrayList<String>();
public ImageAdapter(Context c, LruCache<String, Bitmap> mCache, File gallery) {
mMemoryCache = mCache;
mGalleryDir = gallery;
mInflater = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public View getView(int position, View convertView, ViewGroup parent) {
Log.d("dupa", "getView");
ViewHolder vh;
View cell = convertView;
if (cell == null) {
vh = new ViewHolder();
cell = mInflater.inflate(R.layout.galleryitem, null);
// Populate the ViewHolder
vh.checkBox = (CheckBox) cell.findViewById(R.id.itemCheckBox);
...
cell.setTag(vh);
...
} else {
vh = (ViewHolder) cell.getTag();
}
// Update the cell View state
vh.checkBox.setTag(position);
...
return cell;
}
I've not included xml files because the post is lengthy. If you think they are needed (or you need more code) just tell me. Any help will be greatly appreciated. TIA.
You need to implement onCreateView() in your fragment and return the inflated layout there (note to use the inflate method that doesnt add the inflated view to the container.
http://developer.android.com/reference/android/app/Fragment.html#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)
Just like in the example at the top of the page
/**
* The Fragment's UI is just a simple text view showing its
* instance number.
*/
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.hello_world, container, false);
View tv = v.findViewById(R.id.text);
((TextView)tv).setText("Fragment #" + mNum);
tv.setBackgroundDrawable(getResources().getDrawable(android.R.drawable.gallery_thumb));
return v;
}
There you can remember the instance to the GridView and then in onActivityCreated (or potentially in onAttach() you can set the adapter.

Categories

Resources