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.
Related
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;
}
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);
}
}
I have 2 fragment hosted on an activity with a frame layout, I want to implement fragment communication.I have tried some of the codes, but my requirements are not met. Thanks in advance.!
First fragment: It contains a list .
public class ListWithSearch extends Fragment{
String[] cityName;
String[] cityFact;
int[] cityPic;
ListView list;
ListViewAdapter adapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.city_list_fragment, container,
false);
// Generate sample data
cityName = new String[] { "Delhi", "Chandigarh", "Mumbai", "Bangalore", "Chennai" };
cityFact = new String[] { "China", "India", "United States",
"Indonesia", "Brazil" };
cityPic = new int[] { R.drawable.ic_launcher, R.drawable.ic_launcher,
R.drawable.ic_launcher, R.drawable.ic_launcher,
R.drawable.ic_launcher };
list = (ListView) rootView.findViewById(R.id.listView);
adapter = new ListViewAdapter(getActivity(), cityName,cityPic);
list.setAdapter(adapter);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//To implement
}
});
return rootView;
}
}
Second Fragment: That will be inflated on item click of the list in the first fragment.
public class ResultFragment extends Fragment {
TextView resCityName;
TextView resFact;
ImageView resPic;
String[] cityName;
String[] cityFact;
int[] cityPic;
int position;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return super.onCreateView(inflater, container, savedInstanceState);
}
}
Requirements:
1. ImageView in second fragment to have the same image of the item image in the list.
2. TextViews in second fragment to have data from the list item itself.
In other words, the second fragment is details of the item clicked in the list.
Add the below code to ListWithSearch fragment:
OnListItemSelectListener mCallback;
// Your MainActivity must implement this interface so that ResultFragment can use it
public interface OnListItemSelectListener {
public void onItemSelected(int position, int imageId);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mCallback = (OnListItemSelectListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnListItemSelectListener");
}
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
// Send the event to the host activity
// You can pass the image id to below method. Modify the code as required.
mCallback.onItemSelected(position, imageId);
}
Google provide a great tutorial for this situation here
There plenty of ways to achieve this but take a look on EventBus, it might simplify the job
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;
}
Confused as to why the onClickListener is not responding. Is it because but buttons are set in one layout, but bound to another one? Any help would be appreciated.
public class ActivityList extends ListFragment
{
private ActivityDbAdapter mDbHelper;
private Long mRowId=Long.valueOf(1);
private Activity mContext; //changed to private
AlertDialog activity_relationship;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
mContext=this.getActivity();
mDbHelper=new ActivityDbAdapter(mContext);
mDbHelper.open();
Cursor activity = mDbHelper.fetchAll(mRowId);
View view = (View) inflater.inflate(R.layout.activity_activity_row, container,false);
Button relationship = (Button) view.findViewById(R.id.show_relationship_activities);
String[] from = new String[]{ActivityDbAdapter.COLUMN_NAME_VALUE1_RELATIONSHIP , //from and too.
ActivityDbAdapter.COLUMN_NAME_VALUE1_EDUCATION,
ActivityDbAdapter.COLUMN_NAME_VALUE1_RECREATION,
ActivityDbAdapter.COLUMN_NAME_VALUE1_MIND, ActivityDbAdapter.COLUMN_NAME_VALUE1_DAILY};
int[] to = new int[]{R.id.relationship_value,R.id.education_value, R.id.recreation_value,
R.id.mind_value, R.id.daily_value};
SimpleCursorAdapter contacts =
new SimpleCursorAdapter(mContext, R.layout.activity_activity_row, activity, from, to); //my cursor adapter
relationship.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg) {
Log.e("Why","Are you not working?");
Cursor activity = mDbHelper.fetchAll(mRowId);
String mactivity_relationship=activity.getString( //define all of the Strings. Gahh!!
activity.getColumnIndexOrThrow(ActivityDbAdapter.COLUMN_NAME_ACTIVITY1_RELATIONSHIP));
AlertDialog activity_relationship=new AlertDialog.Builder(mContext).create();
activity_relationship.setTitle("Relationship Activities");
String activities=(mactivity_relationship+"\n"+mactivity_relationship2+"\n"+mactivity_relationship3+
"\n"+mactivity_relationship4+"\n"+mactivity_relationship5);
activity_relationship.setMessage(activities);
activity_relationship.show();
}
});
setListAdapter(contacts);
return inflater.inflate(R.layout.activity_activity_list, container, false);
}
}
As I have it right now, the log is not even showing up.
You may want to return the view that you actually create(and use for getting the Button) in the onCreateView:
//...
return view;
instead of returning a newly inflated layout(and losing the previous Button):
return inflater.inflate(R.layout.activity_activity_list, container, false);
Or add the view to a view from the R.layout.activity_activity_list file that you inflate and return.