Custom listview inside of a fragment - android

I am using a fragment to display a custom listview. The problem is that it doesnt show. But if a I use a normal listview it works. I know that I can use a listfragment. But I need some buttons that there are in fragment layout.
And Also I manage the framents with a tabHost.
class Contactos extends Fragment
private ListView lstContactos;
private AdLstContactos adListaContactos;
#Override
public void onActivityCreated(Bundle state) {
super.onActivityCreated(state);
displayListView();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if(container == null){
return null;
}
return inflater.inflate(R.layout.activity_contactos, container, false);
}
// Aqui se hace los findview
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// lstContactos = (ListView)view.findViewById(R.id.lstContactos);
// adLstContatos = new LstContactos(view.getContext());
// lstContactos.setAdapter(adLstContatos);
}
private void displayListView() {
// create an ArrayAdaptar from the String Array
adListaContactos = new AdLstContactos(getActivity().getApplicationContext());
ListView listView = (ListView) getActivity()
.findViewById(R.id.lstContactos);
// Assign adapter to ListView
listView.setAdapter(adListaContactos);
}
public class AdLstContactos extends ArrayAdapter<String>
private Context context;
private ArrayList<Contactos> datos;
private List<String> urlList;
private TextView txtNombre, txtNumero;
public AdLstContactos(Context contexto) {
super(contexto, R.layout.adaptador_lst_contactos);
this.context = contexto;
//this.datos = datos;
urlList = new ArrayList<String>();
urlList.add("test1");
urlList.add("test1");
urlList.add("test1");
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Create a new view into the list.
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.adaptador_lst_contactos, parent, false);
txtNombre = (TextView)rowView.findViewById(R.id.txtNombreC);
txtNumero = (TextView)rowView.findViewById(R.id.txtNumeroC);
txtNombre.setText(urlList.get(position));
txtNumero.setText(urlList.get(position));
System.out.println("getView");
return rowView;
}
Main activitvy
private FragmentTabHost mTabHost;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mTabHost = new FragmentTabHost(this);
setContentView(mTabHost);
mTabHost.setup(this, getSupportFragmentManager(),
R.layout.activity_principal);
mTabHost.addTab(mTabHost.newTabSpec("DatosPersonales")
.setIndicator("Your Info"),DatosPersonales.class,null);
mTabHost.addTab(mTabHost.newTabSpec("Contactos")
.setIndicator("Contacts"),Contactos.class,null);
}
xml Contactos
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:text="Button" />
<ListView
android:id="#+id/lstContactos"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/button1"
android:layout_below="#+id/button1" >
</ListView>

Probably you have an error in code.
Remember, if you are using custom list you have to do:
create custom adapter wchich extends by ArrayAdapter or BaseAdapter
override "getView()" function in adapter
add some data into adapter
add adapter to list by function "list.setAdapter()"
and it should works but if not then is an error and please add your code.
Here you have example

Contactos
private void displayListView() {
List<String> urlList;
urlList = new ArrayList<String>();
urlList.add("http://www.google.com");
urlList.add("http://mail.google.com");
urlList.add("http://maps.google.com");
// create an ArrayAdaptar from the String Array
adListaContactos = new AdLstContactos(getActivity().getApplicationContext(),urlList);
ListView listView = (ListView) getActivity()
.findViewById(R.id.lstContactos);
// Assign adapter to ListView
listView.setAdapter(adListaContactos);
}
AdLstContactos
public AdLstContactos(Context contexto, List<String>urlList) {
super(contexto, R.layout.adaptador_lst_contactos,urlList);
this.context = contexto;
this.urlList = urlList;
}

Related

ListView not displaying data in fragment using ArrayAdapter

i have a created a fragment in which i want to display listview but my fragment is dislplayed wtihout the listview nor i am getting an error
i have read many solutions to this question but i can't find the right one.
a small help would be great.thank you!
public class ServicesFragment extends Fragment {
public TextView servicesName;
ListView listView;
String[] servicesNameArray;
int[] serviceImages = {
R.drawable.ic_menu_camera,
R.drawable.ic_menu_camera,
R.drawable.ic_menu_camera,
R.drawable.ic_menu_camera,
R.drawable.ic_menu_camera,
R.drawable.ic_menu_camera,
R.drawable.ic_menu_camera,
R.drawable.ic_menu_camera
};
public ServicesFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view= inflater.inflate(R.layout.services_fragment, container, false);
listView = (ListView) view.findViewById(R.id.listView_services);
ServicesAdapter adapter = new ServicesAdapter(getContext(), servicesNameArray, serviceImages);
listView.setAdapter(adapter);
Resources resources = getResources();
resources.getStringArray(R.array.servicesName);
return view;
}
public class ServicesAdapter extends ArrayAdapter<String> {
Context c;
int[] servicesImageArray;
String[] servicesNameArray;
public ServicesAdapter(Context context, String[] servicesNameArray, int[] serviceImages) {
super(context, R.layout.services_layout, R.id.listView_services);
this.c = context;
this.servicesImageArray = serviceImages;
this.servicesNameArray = servicesNameArray;
}
#NonNull
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.services_layout, parent, false);
ImageView serviceImages = (ImageView) view.findViewById(R.id.image_of_services);
TextView servicesName = (TextView) view.findViewById(R.id.name_of_services);
serviceImages.setImageResource(servicesImageArray[position]);
servicesName.setText(servicesNameArray[position]);
return view;}}}
You are not assigning value to the string array: use
servicesNameArray = getResources().getStringArray(R.array.servicesName);
and instead of :
ServicesAdapter adapter = new ServicesAdapter(getContext(), servicesNameArray, serviceImages);
use the activity context:
ServicesAdapter adapter = new ServicesAdapter(this.getActivity(), servicesNameArray, serviceImages);
you need to notify you adapter about your data set size:
super(context, R.layout.services_layout, servicesNameArray); //change here
I think this issue cause you dont pass data in correct way
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view= inflater.inflate(R.layout.services_fragment, container, false);
Resources resources = getResources();
servicesNameArray = resources.getStringArray(R.array.servicesName);
listView = (ListView) view.findViewById(R.id.listView_services);
ServicesAdapter adapter = new ServicesAdapter(getContext(), servicesNameArray, serviceImages);
listView.setAdapter(adapter);
return view;
}

Error Image listview fragment

enter image description hereBelow is the coding i have and it seems i have problem on the
AgentAdapter adapter = new AgentAdapter(getActivity(), R.layout.list_agent, member_names, profile_pics);
How do i use image and text together for the list adapter i have in my fragment? Please help.
public class AgentFragment extends Fragment{
String[] member_names;
TypedArray profile_pics;
ListView mylistview;
String[] agentname={"Robert","Shanni","Rachel","Mady","Nikhil"};
Integer [] imgid = {R.drawable.robert,R.drawable.shanni,R.drawable.rachael,R.drawable.maddy_pic,R.drawable.nikhil_pic};
public AgentFragment(){
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.list_layout1, null);
setupList(view);
return view;
}
private void setupList(View view){
AgentAdapter adapter = new AgentAdapter(getActivity(), R.layout.list_agent, member_names, profile_pics);
mylistview = (ListView) view.findViewById(R.id.listView);
mylistview.setAdapter(adapter);
}
}
Since its possible that the fragment has not been placed in any activity at runtime you can afford for this by changing the getActivity() to be the context from the view parameter:
private void setupList(View view){
AgentAdapter adapter = new AgentAdapter(view.getContext(), R.layout.list_agent, member_names, profile_pics);
mylistview = (ListView) view.findViewById(R.id.listView);
mylistview.setAdapter(adapter);
}

Custom arrayadapter combines lists used in different fragments of same activity

I have MainActivity activity which has 3 fragments. Those 3 fragments use same arrayadapter class MessageListAdapter. When i populate listView in my fragments using different ArrayLists using MessageListAdapter it combines all those ArrayLists and displays in each fragment. I want each fragment to display its own list.
MessageListAdapter:
public class MessageListAdapter extends ArrayAdapter<Message>{
Context context;
public MessageListAdapter(Context c, int resourceId, ArrayList<Message> list) {
super(c, resourceId, list);
this.context = c;
}
//...
}
HomeFragment:
public class HomeFragment extends Fragment {
View view;
ListView listView1;
ArrayList<Message> contactMessages;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.home_layout, container, false);
TextView welcomeMessage = (TextView) view.findViewById(R.id.welcomeMessage);
Account acc = new Account();
welcomeMessage.setText("Welcome " + acc.getName() + "!");
contactMessages = new Message().getContactMessages();
listView1 = (ListView) view.findViewById(R.id.homeList);
MessageListAdapter adapter = new MessageListAdapter(this.getActivity(), R.layout.activity_message, contactMessages);
listView1.setAdapter(adapter);
listView1.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// TODO Auto-generated method stub
}
});
return view;
}
}
ProfileFragment:
public class ProfileFragment extends Fragment implements View.OnClickListener, OnItemClickListener {
View view;
Intent intent;
ListView listView2;
ArrayList<Message> personalMessages;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.profile_layout, container, false);
Button button = (Button) view.findViewById(R.id.addMessage);
button.setOnClickListener(this);
Button addFriendButton = (Button) view.findViewById(R.id.addFriend);
addFriendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
intent = new Intent(getActivity(), AddFriendActivity.class);
startActivity(intent);
}
});
personalMessages = new Message().getPersonalMessages();
// Log.i("Personal messages ArrayList: ", personalMessages.toString());
listView2 = (ListView) view.findViewById(R.id.profileList);
MessageListAdapter adapter = new MessageListAdapter(this.getActivity(), R.layout.activity_message, personalMessages);
listView2.setAdapter(adapter);
listView2.setOnItemClickListener(this);
return view;
}
}
Also have 3rd fragment which will use this same MessageListAdapter, but i have not implemented it yet due to running into this problem.
I made screenshots to make it easier to understand:
Items with orange pictures are supposed to be shown only in ProfileFragment and item with blue picture is supposed to be shown only in HomeFragment
Problem lies in using static ArrayList inside Message class. addPersonalMessage adds Message object into personalMessages list and addContactMessage adds Message object into contactMessages list. After i built all the messages according to their type and put them inside lists separately, for some reason application combines those 2 lists. This is why i end up with similar content in both listviews in fragments. Solved problem by using SQLite database instead of using static variables.
Message:
public class Message {
private String author;
private String messageTitle;
private Bitmap messageImage;
private static ArrayList<Message> personalMessages = new ArrayList<Message>();
private static ArrayList<Message> contactMessages = new ArrayList<Message>();
public Message() {
}
public Message(String a, String t, Bitmap b) {
this.author = a;
this.messageTitle = t;
this.messageImage = b;
}
public void addPersonalMessage() {
personalMessages.add(this);
}
public void addContactMessage() {
contactMessages.add(this);
}
}

Load listView in new Fragment standard of Android instead of Activity

Today I was making a new app when I saw the normal way of constructing activities had changed. I'm trying to fill a listview with data from my database but I cannot get it to work. The rootview is the problem I'm guessing.
Following code is an old activity example that works as it should (I tested it):
public class TrackNewActivity extends Activity {
List<TrackSave> tracks = new ArrayList<TrackSave>();
private DatabaseHelper db;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_track_save);
db = new DatabaseHelper(this);
tracks = db.getAllSavedTracks();
fillTracks();
}
private void fillTracks() {
TrackAdapter trackAdapter = new TrackAdapter(getApplicationContext(),
tracks);
final ListView listView = (ListView) findViewById(R.id.listView);
listView.setAdapter(trackAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parentView, View childView,
int position, long id) {
}
});
}
}
Note the setContentView is set to a fragment view I actually want to use. This fragment_track_save.java just contains a Linearlayout with a listview to diplsay the items.
Unfortunately following code does not work where I try to get the same as old activity example:
public class TrackSaveActivity extends ActionBarActivity {
List<TrackSave> tracks = new ArrayList<TrackSave>();
static View rootView;
private DatabaseHelper db;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_track);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
db = new DatabaseHelper(this);
tracks = db.getAllSavedTracks();
fillTracks();
}
private void fillTracks() {
TrackAdapter trackAdapter = new TrackAdapter(getApplicationContext(),
tracks);
final ListView listView = (ListView) rootView
.findViewById(R.id.listView);
listView.setAdapter(trackAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parentView, View childView,
int position, long id) {
}
});
}
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_track_save,
container, false);
return rootView;
}
}
}
The problem here occurs when I try to find the listview. It always refers to a nullpointer exception because it cannot find the listview, that's my guess.
activity_track.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="*.TrackActivity"
tools:ignore="MergeRootFrame" />
Hopefully I made it clear.
If you want to use a fragment you should have a MainActivity with something like this:
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.add(R.id.container, new MyFragment())
.commit();
}
}
}
Then, a class for the Fragment, in this case a ListFragment:
public class MyFragment extends ListFragment {
public MyFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
ArrayList<String> la = new ArrayList<String>();
la.add("Item1");
la.add("Item2");
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, la);
setListAdapter(adapter);
return rootView;
}
fragment_main Should look something like this:
<LinearLayout
// ....>
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>

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.

Categories

Resources