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.
Related
I have two fragments Fragment A and Fragment B. The FragmentA dynamically adds a view with onclickListner(Fragment B, that means fragment B listens ) to fragment B.Now when i click on added view (added by fragment A) in Fragment B, it doesn't work.
Here is my code.
Fragment A
LayoutInflater layoutInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View last_user_layout = layoutInflater.inflate(R.layout.single_row_lastchatuser, null);
LinearLayout row_user = (LinearLayout) last_user_layout.findViewById(R.id.Llastchatuser);
row_user.setOnClickListener(new LastUsers());
if (row_user.getParent() != null)
((ViewGroup) row_user.getParent()).removeView(row_user);
LinearLayout linearLayout = (LinearLayout) getActivity().findViewById(R.id.last_user_container);
linearLayout.addView(row_user);
//it successfully adds view in fragment B
Fragment B (Last users)
public class LastUsers extends Fragment implements View.OnClickListener {
public LastUsers() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_last_users, container, false);
return view;
}
#Override
public void onClick(View view) {
if(view.getId()==R.id.Llastchatuser){
Toast.makeText(getContext(),"called",Toast.LENGTH_LONG).show();
}
}
}
Try this:
row_user.setDuplicateParentStateEnabled(true);
row_user.setClickable(true);
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
I have 3 different layouts on my ViewPagerIndicator - https://github.com/JakeWharton/Android-ViewPagerIndicator
My project is to load data from the website and set the data accordingly into the 3 different layout of the ViewPager.
How do I go about achieving it?
In my TestFragment, I have
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.i("mContent", mContent);
View view = null;
if (mContent.equalsIgnoreCase("title1")) {
view = inflater.inflate(R.layout.one, container, false);
} else if (mContent.equalsIgnoreCase("title2")) {
view = inflater.inflate(R.layout.two, container, false);
} else if (mContent.equalsIgnoreCase("title3")) {
view = inflater.inflate(R.layout.three, container, false);
//Textview data = (TextView)view.findViewById(id)
}
return view;
}
I know this is for setting layout according to the fling'd titles.
I know how to findViewById to get the id of the widgets and set data. However, the data is set statically in the code itself.
For me, I have to grab data from the internet and put the data in accordingly. How do I achieved that?
Thanks in advance.
I almost know what you want.Here is my answers,and it works well.
You can according to the following steps.
1.Create three different Fragment class ,such as LoadImageFragment1,LoadImageFragment2,LoadImageFragment3, and all of them extends Fragment.
Follow is my example.
public class LoadImageFragment1 extends Fragment {
ListView listView;
LayoutInflater mInflater;
LoadImageAdapter adapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mInflater = inflater;
View view = inflater.inflate(R.layout.loadimage_layout, null);
listView = (ListView) view.findViewById(R.id.listview);
adapter = new LoadImageAdapter();
adapter.initList();
listView.setAdapter(adapter);
return view;
}
private class LoadImageAdapter extends BaseAdapter{
ArrayList<String> list = new ArrayList<String>();
public void initList(){
for(int i = 0 ; i < 30;i ++){
list.add("" + i);
}
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null){
convertView = mInflater.inflate(R.layout.loadimage_item, null);
}
return convertView;
}
}
2.Then modify your SampleTabsDefault class.
class GoogleMusicAdapter extends FragmentPagerAdapter {
public GoogleMusicAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
// return TestFragment.newInstance(CONTENT[position % CONTENT.length]);
switch(position){
case 0:
return new LoadImageFragment1();
case 1:
return new LoadImageFragment2();
case 2:
return new LoadImageFragment3();
}
}
#Override
public CharSequence getPageTitle(int position) {
return CONTENT[position % CONTENT.length].toUpperCase();
}
#Override
public int getCount() {
return CONTENT.length;
}
}
And I just use the class of SampleTabsDefault as a sample.You can do this in other classes.
Here I just use a ListView as a sample , you can load your images and texts from internt, and you also can do other things in your LoadImageAdapter 's getView() method.
Hope this can help you.
I have 3 different layouts on my ViewPagerIndicator
ViewPagerIndicator is just an indicator
I thought your meaning is your viewadapter have three views to show.
Use FragmentPagerAdapter to handle different view.
you should read the ViewPagerIndicator samples
Before starting, copy the samples from ViewPagerIndicator
https://github.com/JakeWharton/Android-ViewPagerIndicator/tree/master/sample/src/com/viewpagerindicator/sample
The steps to be done are,
Create an custom FragmentPagerAdapter (ex: https://github.com/JakeWharton/Android-ViewPagerIndicator/blob/master/sample/src/com/viewpagerindicator/sample/TestFragmentAdapter.java)
Create custom Fragment for each each layout (in your case 3)
https://github.com/JakeWharton/Android-ViewPagerIndicator/blob/master/sample/src/com/viewpagerindicator/sample/TestFragment.java
Override onActivityCreated in the fragment class
In the onActivityCreated method, u can access the UI components as in onCreate method
So that u can make a web service call, bind it to ur UI components in this segment.
Cheers
Create and implement a Loader (AsyncTaskLoader) to load data from the internet.
Have your TestFragment implement LoaderCallbacks, so that it gets notified when the Loader (AsyncTaskLoader) has finished loading data from the internet.
In your implementation of your TestFragment's onActivityCreated, initialize or restart the loader:
getLoaderManager().initLoader(0, null, this);
In your TestFragment's implementation of onLoadFinished, assign the data to the widgets.
https://developer.android.com/reference/android/content/AsyncTaskLoader.html
https://developer.android.com/reference/android/app/LoaderManager.html
https://developer.android.com/reference/android/app/LoaderManager.LoaderCallbacks.html
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.
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);