I want to implement GridView that each cell contains an object of class. for this I implemented fragment class:
public class DayUC extends Fragment {
/*
some variables
*/
// use to create instance of class with initial parameters
public static DayUC newInstance(//initial parameters) {
DayUC dayUC = new DayUC();
/*
set parameters
*/
return dayUC;
}
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_layout, container, false);
initialization() //initial variables and view elemans (textView, ...)
return rootView;
}
}
and also I created GridViewAdapter:
public class GridViewAdapter extends BaseAdapter {
private ArrayList<DayUC> gridList; //list of grid DayUC objects
Context context;
public GridViewAdapter(Context context, ArrayList<DayUC> gridList) {
this.gridList = gridList;
this.context = context;
}
#Override
public int getCount() {
return gridList.size();
}
#Override
public DayUC getItem(int position) {
return gridList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
return gridList.get(position).getView();
}
}
but when I create GridView it throws NullPointerException! I found that in gridView elements (DayUC) onCreateView() never called. so gridList.get(position).getView() returns null!!
could anyone help me to solve this problem? how could I force onCreateView to be called??
Edit: MainActivity onCreate method added:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DayUC[] dayUC = new DayUC[42];
monthGridView = (GridView) findViewById(R.id.month_view);
for (int i = 0; i < 42; i++) {
dayUC[i] = DayUC.newInstance(//inpute arguments)
dayUCList.add(dayUC[i]);
monthCal.add(Calendar.DATE, 1);
}
gridViewAdapter = new MonthGridViewAdapter(getActivity(), dayUCList);
monthGridView.setAdapter(gridViewAdapter);
gridViewAdapter.notifyDataSetChanged();
}
Related
I am trying to use this example on the official android tutorial site and translating it into a gridview inside a fragment that uses picasso to load images.
I am looking at my code and I can't figure out what is wrong. The images simply won't load and all I get is a blank screen. What am I missing here?
My fragment code:
public class MainFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main, container, false);
GridView gridView = (GridView) view.findViewById(R.id.gridview);
gridView.setAdapter(new ImageAdapter(getActivity().getApplicationContext()));
return view;
}
}
My custom adapter:
public class ImageAdapter extends BaseAdapter {
private Context mContext;
public ImageAdapter(Context c){
mContext = c;
}
#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) {
ImageView imageView;
if(view == null){
imageView = new ImageView(mContext);
}
else{
imageView = (ImageView) view;
}
Picasso.with(mContext).setLoggingEnabled(true);
Picasso.with(mContext)
.load(eatFoodyImages[i])
.fit()
.into(imageView);
return imageView;
}
#Override
public int getCount() {
return 0;
}
public static String[] eatFoodyImages = {
"http://i.imgur.com/rFLNqWI.jpg",
"http://i.imgur.com/C9pBVt7.jpg",
"http://i.imgur.com/rT5vXE1.jpg",
"http://i.imgur.com/aIy5R2k.jpg",
"http://i.imgur.com/MoJs9pT.jpg",
"http://i.imgur.com/S963yEM.jpg",
"http://i.imgur.com/rLR2cyc.jpg",
"http://i.imgur.com/SEPdUIx.jpg",
"http://i.imgur.com/aC9OjaM.jpg",
"http://i.imgur.com/76Jfv9b.jpg",
"http://i.imgur.com/fUX7EIB.jpg",
"http://i.imgur.com/syELajx.jpg",
"http://i.imgur.com/COzBnru.jpg",
"http://i.imgur.com/Z3QjilA.jpg",
};
}
My activity:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(savedInstanceState == null){
getSupportFragmentManager()
.beginTransaction().add(R.id.mainfragment, new MainFragment())
.commit();
}
}
}
#Override
public int getCount() {
return eatFoodyImages.length;
}
I have android application.
Application minSDK:15
I have NavigationDrawer.
When click on first Navigation drawer menu item, my new fragment appears called MainFragment.
Everything is good, like in android tutorial.
Now in this fragment I need to implement simple ViewPager.
ViewPager will page Fragments.
Here is code:
public class MainFragent extends Fragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.main_fragment_layout, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ArrayList<Books> books;
BooksPageAdapter contentPageAdapter = new BooksPageAdapter(getFragmentManager(), books);
ViewPager pager = (ViewPager) getActivity().findViewById(R.id.viewPager);
pager.setAdapter(contentPageAdapter);
}
private class BooksPageAdapter extends FragmentStatePagerAdapter {
private ArrayList<Books> books;
public BooksPageAdapter(FragmentManager fm, private ArrayList<Books> books) {
super(fm);
this.books = books;
}
#Override
public Fragment getItem(int pos) {
return BooksFragment.newInstance(books);
}
#Override
public int getCount() {
return 5;
}
} }
And BooksFragment:
public class BooksFragment extends Fragment {
private ArrayList<Books> books;
static ContentFragment newInstance(final ArrayList<Books> books) {
BooksFragment booksFragment = new BooksFragment();
Bundle args = new Bundle();
args.putSerializable("books", books);
contentFragment.setArguments(args);
return booksFragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
books = (ArrayList<Books>) getArguments().getSerializable(“books”);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_books, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public void onResume() {
super.onResume();
updateUI(books);
}
public void updateUI(ArrayList<Books> books) {
ListView listView = (ListView)getActivity().findViewById(R.id.list_view);
listView.setAdapter(new MyArrayAdapter(getActivity(), books));
}
private class MyArrayAdapter extends ArrayAdapter<Books> {
public MyArrayAdapter(final Context context, final List<Books> list) {
super(context, R.layout.books_menu_item, R.id.title, list);
}
#Override
public View getView(final int position,
final View convertView,
final ViewGroup parent) {
final View row = super.getView(position, convertView, parent);
Book book = getItem(position);
textView.setText(book.getTitle());
return row;
}
}
}
The FirstPage looks awesome, like it should. I see list of books titles.
But on the second page, list view is empty. All other views on second page (like TextView..) are fine except ListView.
What I do wrong ?
P.S FragmentStatePageAdapter is from support13. Fragments are from android package, not from support4
I'm making an app that displays events in a list. Each event has a custom layout (with BaseAdapter). If i'm using my phone in either only portrait or only landscape its ok, but if i'm on the list and rotate my phone to change the orientation the BaseAdapter produces a NullPointerException. Here is the code:
public class ShowListAdapter extends BaseAdapter {
private Activity a;
private List<Map<String, String>> monthList;
private static LayoutInflater inflater;
public ShowListAdapter(Activity act, List<Map<String, String>> msc) {
a = act;
monthList = msc;
inflater = (LayoutInflater) a.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
return monthList.size();
}
public Object getItem(int i) {
return i;
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
View v = view;
if (view == null) {
v = inflater.inflate(R.layout.list_item, null);
}
/* Some random code that formats the view goes here */
return v;
}
}
The error is thrown at getCount(), because it (i assume) can not find the list variable monthList.
This class is used in a ListFragment class
public class ListForMonth extends ListFragment {
List<Map<String, String>> eventListLoc;
public ListForMonth() {}
public ListForMonth(int i) {
eventListLoc = ShowHolder.eventList.get(i);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
setListAdapter(new ShowListAdapter(this.getActivity(), eventListLoc));
return super.onCreateView(inflater, container, savedInstanceState);
}
}
The ShowHolder class has a single static variable that is "generated" in the splash screen of the application.
The main Activity has multiple tabs, each it's own ListFragment. The only important part of the code in there is this, i guess:
public Fragment getItem(int position) {
return new ListForMonth(position);
}
Why does the code throw this error? And how can i fix it? Thanks in advance!
You are right the problem is in this lines..
public Fragment getItem(int position) {
return new ListForMonth(position);
}
when ever the orientation changes Android calls the fragmnet with the default constructor..at that time your List> eventListLoc data is null..thats why it is giving NPE..
To avoid this..Change your fragment code like thiss..
public class ListForMonth extends ListFragment {
List<Map<String, String>> eventListLoc;
private int i;
public ListForMonth() {
}
public ListForMonth(int i) {
this.i = i;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
i = savedInstanceState.getInt("POSITION");
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
eventListLoc = ShowHolder.eventList.get(i);
setListAdapter(new ShowListAdapter(this.getActivity(), eventListLoc));
return super.onCreateView(inflater, container, savedInstanceState);
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("POSITION", i);
}
}
Watch out because when you switch from landscape to portrait or from portrait to landscape, the activity restarts. So override the onResume() method and handle the screen orientation.
I have a FragmentActivity that uses a ViewPager to flip left and right through pages of data (two ListFragments).
public class StopsActivity extends FragmentActivity {
private ViewPager mViewPager;
private PagerTabStrip mPagerTabStrip;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_stops);
mPagerTabStrip =(PagerTabStrip)findViewById(R.id.pager_header);
mViewPager = (ViewPager)findViewById(R.id.pager);
mPagerTabStrip.setDrawFullUnderline(true);
mPagerTabStrip.setTabIndicatorColorResource(R.color.pagerTabStrip);
mViewPager.setAdapter(new StopsAdapter(getSupportFragmentManager()));
mViewPager.setCurrentItem(0);
}
private class StopsAdapter extends FragmentPagerAdapter {
public StopsAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return StopsFragment.newInstance(routename, Stop.FORWARD);
case 1:
return StopsFragment.newInstance(routename, Stop.BACKWARD);
}
return null;
}
#Override
public int getCount() { return 2;}
#Override
public CharSequence getPageTitle(int position) { /* implementation ... */}
}
}
Everything runs ok, but I think that the instantation of the second StopFragment invalidate the data of the first one when getItem is called.
public class StopsFragment extends ListFragment {
private StopsAdapter mStopsAdapter;
private ListView mListView;
private String routename;
private int direction;
public static StopsFragment newInstance(String routename, int direction) {
StopsFragment stopsFragment = new StopsFragment();
// Supply arguments
Bundle args = new Bundle();
args.putString("routename", routename);
args.putInt("direction", direction);
stopsFragment.setArguments(args);
return stopsFragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Setup the adapter
ArrayList<Stop> stops = ...
mStopsAdapter = new StopsAdapter(getActivity(), stops);
setRetainInstance(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle inState) {
View rootView = inflater.inflate(R.layout.fragment_stops, container, false);
// Attach the adapter
mListView = (ListView) rootView.findViewById(android.R.id.list);
mListView.setAdapter(mStopsAdapter);
return rootView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
}
The page "IDA" corresponds to StopFragment with argument Stop.FORWARD and the page "VUELTA" corresponds the StopFragment with argument Stop.BACKWARD. As you can see in the images below, just one of them (the last one instantiate) is populated:
What I'm doing wrong?
EDIT
This is StopsAdapter
class StopsAdapter extends BaseAdapter {
private ArrayList<Stop> stops;
private LayoutInflater inflater;
public StopsAdapter(Context context, ArrayList<Stop> stops) {
this.stops = stops;
this.inflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return stops.size();
}
#Override
public Object getItem(int position) {
return stops.get(position);
}
#Override
public long getItemId(int position) {
return (long)position;
}
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.item_stop, parent, false);
}
TextView name = (TextView)convertView.findViewById(R.id.tvStopName);
TextView description = (TextView)convertView.findViewById(R.id.tvStopDescription);
Stop stop = (Stop)getItem(position);
name.setText(stop.name);
if (stop.info != null) {
description.setText(stop.info);
}
return convertView;
}
}
Ok, my fault. The code that was giving me problems is the only that I haven't posted (ArrayList<Stop> stops = ...). The code about Fragments and ViewPager works correctly.
I have a CarsFragment which is inculde cars. One page is one trade (Ferrari, Mercedes) and on every page has a list with models of actual trade.
The main view:
public class CarsFragment extends Fragment {
#Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.cars_fragment, container, false);
pager = (ViewPager) view.findViewById(R.id.carsPager);
adapter = new CarsPagerAdapter(getChildFragmentManager());
pager.setAdapter(adapter);
return view;
}
}
Adapter:
public class CarsPagerAdapter extends FragmentStatePagerAdapter {
private final FragmentManager fm;
private String[] cars = new String[]{"Ferrari","Mercedes"};
public MatchesPageAdapter(final FragmentManager fm) {
super(fm);
this.fm = fm;
}
#Override
public int getCount() {
return cars.length;
}
#Override
public Fragment getItem(final int position) {
return FragmentModelList.newInstance(cars[position]);
}
#Override
public void destroyItem(final ViewGroup container, final int position, final Object object) {
super.destroyItem(container, position, object);
}
}
List:
public class FragmentModelList extends Fragment {
public static FragmentModelList newInstance(String trade) {
FragmentModelList fragmentModelList = new FragmentModelList();
Bundle args = new Bundle();
args.putString("trade", trade);
fragmentModelList.setArguments(args);
return fragmentModelList;
}
#Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_matches_list_view, container, false);
list = (ListView) view.findViewById(R.id.modelList);
return view;
}
#Override
public void onActivityCreated(final Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
modelListAdapter = new ModelListAdapter(getActivity());
list.setAdapter(modelListAdapter);
loadModels();
}
private void loadModels() {
new AsyncTask<Void, Void, Boolean>() {
#Override
protected Boolean doInBackground(final Void... params) {
try {
List<Model> result = Downloader.getModelsByName(getArguments().getString("trade"));
modelListAdapter.setData(result);
return true;
} catch (Exception ex) {
return false;
}
}
#Override
protected void onPostExecute(final Boolean success) {
if (!success) {
// Show error
} else {
// Update list
modelListAdapter.notifyDataSetChanged();
}
}
}.execute();
}
}
and the modelListAdapter set row where one row inculde 2 image and some textview.
And the problem:
when i swiping on the viewpager it isn't smooth :( a loged it and when created the next or previous page (depends on swipe direction) the animation will be bad, is lagging.
What is the solution?
(SGS4 android 4.2.2 - where is the project butter :(( )