J'essaye d'implémenter une activité avec un viewpager et deux onglets afin de permettre des gestes de balayage entre les sections, chacune contenant une listview avec un adaptateur personnalisé qui charge les données d'un asynctask. Je voudrais montrer un spinner de chargement pendant le chargement des données. Si nous utilisons une listview normale avec un simple adaptateur, cela fonctionne. Le problème se pose lorsque nous introduisons un adaptateur personnalisé pour les vues de liste. Eclipse renvoie l'erreur suivante:Comment implémenter listview avec fragment, adaptateur personnalisé, onglets et viewpager dans android
FATAL EXCEPTION: main java.lang.NullPointerException at libraries.BoostAdapter.getCount(BoostAdapter.java:58) at android.widget.ListView.setAdapter(ListView.java:466) at kasuga.gamble.roma.LikeAttendList$AppSectionsPagerAdapter$LikeFragmentList.onActivityCreated(LikeAttendList.java:237) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:891) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1080) at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:622) [...]
Tout conseil serait le bienvenu! Je vous remercie.
L'activité (par souci de simplicité, considérons un seul ListFragment)
public class LikeAttendList extends FragmentActivity implements ActionBar.TabListener { AppSectionsPagerAdapter mAppSectionsPagerAdapter; //ListView Adapter static BoostAdapter adapterLike; static BoostAdapter adapterAttend; ViewPager mViewPager; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.attendlike); //Retrieve intent extras: event Id Intent i2 = getIntent(); uid = i2.getExtras().getString("eventid"); //Adapter creation Log.e("LikeAttend Report", "Entering LikeAttendList, eventID: " + uid); // Create the adapter that will return a fragment for each of the two sections // of the app. mAppSectionsPagerAdapter = new AppSectionsPagerAdapter(getSupportFragmentManager()); // Set up the action bar. final ActionBar actionBar = getActionBar(); // Specify that the Home/Up button should not be enabled, since there is no hierarchical // parent. actionBar.setHomeButtonEnabled(false); // Specify that we will be displaying tabs in the action bar. actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); // Set up the ViewPager, attaching the adapter and setting up a listener for when the // user swipes between sections. mViewPager = (ViewPager) findViewById(R.id.pager); mViewPager.setAdapter(mAppSectionsPagerAdapter); mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { @Override public void onPageSelected(int position) { // When swiping between different app sections, select the corresponding tab. // We can also use ActionBar.Tab#select() to do this if we have a reference to the // Tab. actionBar.setSelectedNavigationItem(position); } }); // For each of the sections in the app, add a tab to the action bar. for (int i = 0; i < mAppSectionsPagerAdapter.getCount(); i++) { // Create a tab with text corresponding to the page title defined by the adapter. // Also specify this Activity object, which implements the TabListener interface, as the // listener for when this tab is selected. actionBar.addTab( actionBar.newTab() .setText(mAppSectionsPagerAdapter.getPageTitle(i)) .setTabListener(this)); } } /** * A FragmentPagerAdapter that returns a fragment corresponding to one of the primary * sections of the app. */ public static class AppSectionsPagerAdapter extends FragmentPagerAdapter { public AppSectionsPagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int i) { switch (i) { case 0: // The first section of the app shows all likes. return new LikeFragmentList(); //The second should show all user who will attend the event default: // The other sections of the app are dummy placeholders. Fragment fragment = new DummySectionFragment(); Bundle args = new Bundle(); args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, i + 1); fragment.setArguments(args); return fragment; } } public static class LikeFragmentList extends ListFragment { private ListView listv; private BoostAdapter adapter; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //retrieves data from asyncTask LikeAttendList mc = new LikeAttendList(); mc. new EventDataTask().execute(uid); //Sets up the adapter Activity ctx = this.getActivity(); adapterLike = new BoostAdapter(ctx, userList); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v1 = inflater.inflate(R.layout.likelist, container, false); listv = (ListView) v1.findViewById(android.R.id.list); return v1; } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); //ArrayAdapter<String> adapter = new ArrayAdapter<String>(inflater.getContext(), android.R.layout.simple_list_item_1,countries); listv.setAdapter(adapterLike); /* Trying to implement a cross fade transition, we should use an xml with the listview and the loading spinner, all advices //Cross Fade transition views // save the content mContentView = getView().findViewById(R.id.likelist); // save the loading spinner mLoadingView = getView().findViewById(R.id.loading_spinner); // remove content mContentView.setVisibility(View.GONE); // save the animation duration mAnimationDuration = getResources().getInteger(android.R.integer.config_longAnimTime); */ } } public String[] titles= { "Likes", "Attends" }; @Override public int getCount() { return titles.length; } @Override public CharSequence getPageTitle(int position) { return titles[position]; } } public static class DummySectionFragment extends Fragment { public static final String ARG_SECTION_NUMBER = "section_number"; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_section_dummy, container, false); Bundle args = getArguments(); ((TextView) rootView.findViewById(android.R.id.text1)).setText( getString(R.string.dummy_section_text, args.getInt(ARG_SECTION_NUMBER))); return rootView; } } @Override public void onTabReselected(Tab tab, FragmentTransaction ft) { // TODO Auto-generated method stub } @Override public void onTabSelected(Tab tab, FragmentTransaction ft) { // When the given tab is selected, switch to the corresponding page in the ViewPager. mViewPager.setCurrentItem(tab.getPosition()); } @Override public void onTabUnselected(Tab tab, FragmentTransaction ft) { } private class EventDataTask extends AsyncTask<String, Void, JSONObject> { //Returns a ArrayList<HashMap<String, String>> with datas called userlist used to populate listview. cf: onCreate in LikeFragmentList() private View mContent; private View mSpinner; private int mDuration; public EventDataTask() { eventsFunctions = new EventsFunctions(); } protected JSONObject doInBackground(String... uid) { Log.e("Social","List Requested: num item: " + max_item +" page number: " + current_page); // getting JSON string from URL current_page=1; String eventId=uid[0]; return eventsFunctions.eventList(Integer.toString(current_page),Integer.toString(max_item),TAG_ACTIVITY, eventId); } @Override protected void onPostExecute(JSONObject json) { // Check your log cat for JSON reponse //Log.e("All Socials list data Once: ", json.toString()); userList = new ArrayList<HashMap<String, String>>(); try { // Checking for SUCCESS TAG String success = json.getString(TAG_SUCCESS); if (success != null) { if (Integer.parseInt(json.getString(TAG_SUCCESS)) != 0) { JSONArray like = json.getJSONArray("likes"); for (int i = 0; i < like.length(); i++) { JSONObject c = like.getJSONObject(i); String name = c.getString(TAG_NAME); String score = c.getString(TAG_SCORE); String photo = c.getString(TAG_PHOTO); // creating new HashMap HashMap<String, String> firstItemMap = new HashMap<String, String>(); // adding each child node to HashMap key => value firstItemMap.put(TAG_SCORE, score); firstItemMap.put(TAG_NAME, name); firstItemMap.put(TAG_PHOTO, photo); // adding HashList to ArrayList userList.add(firstItemMap); } for (int j=0; j< userList.size(); j++) { //Log.e("AllEvents Reporter", "Torneo numero: "+ j + " Nome: " + tornei.get(j).getName()); Log.e("Social Reporter", "utente numero: "+ j + " Nome: " + userList.get(j).get(TAG_NAME)); } } } } catch (JSONException e) { e.printStackTrace(); } super.onPostExecute(json); } } }
-Custom BoostAdapter créé:
public class BoostAdapter extends BaseAdapter
{
private static String logo_path = "http://userk.servehttp.com/Gamble/Immagini/Pokeroom/All/";
// JSON Node names
private static final String TAG_SUCCESS = "success";
private static final String TAG_PEOPLE = "people";
private static final String TAG_UID = "uid";
private static final String TAG_NAME = "name";
private static final String TAG_RANKING = "ranking";
private static final String TAG_PROFILEPICTURE = "photo";
private static final String TAG_EVENTUID = "eventuid";
EventsFunctions eventsFunctions;
Bitmap bitmapLogo;
Bitmap bit;
private static LayoutInflater inflater=null;
public ImageLoader imageLoader;
private ArrayList<HashMap<String, String>> people;
private Activity context;
public BoostAdapter()
{
super();
}
public BoostAdapter(Activity ctx, ArrayList<HashMap<String, String>> persons)
{
super();
context = ctx;
people = persons;
inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader=new ImageLoader(context.getApplicationContext());
}
public int getCount()
{
return people.size();
}
public Object getItem(int position)
{
return people.get(position);
}
public long getItemId(int position)
{
return position;
}
static class ViewHolder
{
public TextView row_name;
public TextView rankinglist;
public ImageView image;
}
public View getView(int position, View convertView, ViewGroup parent)
{
View vi=convertView;
if(convertView==null)
{
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
vi = inflater.inflate(R.layout.list_item, null);
ViewHolder viewholder = new ViewHolder();
viewholder.row_name= (TextView) vi.findViewById(R.id.row_name);
viewholder.rankinglist= (TextView) vi.findViewById(R.id.rankinglist);
viewholder.image = (ImageView) vi.findViewById(R.id.row_icon);
vi.setTag(viewholder);
}
//Log.e("BassAdapter Reporter","Checking infos retrivial: Received event: " + Integer.toString(position) + " of " +Integer.toString(tornei.size()) +
// " Infos:\n Name: "+ tornei.get(position).get(TAG_NAME) + " logo: " + tornei.get(position).get(TAG_LOGO) +" Gtd: " + tornei.get(position).get(TAG_GTD).length() +"Buyin: "+ tornei.get(position).get(TAG_BUYIN) + " partecipanti " + tornei.get(position).get(TAG_PARTECIPANTI));
ViewHolder holder = (ViewHolder) vi.getTag();
holder.row_name.setText(people.get(position).get(TAG_NAME));
holder.row_name.setMaxLines(1);
holder.rankinglist.setText(people.get(position).get(TAG_RANKING));
if (people.get(position).get(TAG_PROFILEPICTURE)!="")
{
String url2 = logo_path + people.get(position).get(TAG_PROFILEPICTURE);
//Log.e(" Adapter report:", tornei.get(position).getName() + " and its image path is " + url2);
Log.e("Adapter report:", "Item " + Integer.toString(position) + " of " +Integer.toString(people.size()));
imageLoader.DisplayImage(url2, holder.image);
}
return vi;
}
}
Ce sont les xml nécessaires:
- likelist
attendlike.xml
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/pager" android:layout_width="match_parent" android:layout_height="match_parent" />
attendlikelistitem
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="50dp" android:orientation="horizontal" android:cacheColorHint="#00000000" > <ImageView android:id="@+id/row_icon" android:layout_width="50dp" android:layout_height="50dp" android:padding="5dp" android:src="@drawable/ic_launcher" /> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" android:baselineAligned="false" android:paddingLeft="7dp" android:paddingTop="5dp"> <TextView android:id="@+id/row_name" android:layout_width="wrap_content" android:layout_height="fill_parent" android:text="@string/namelist" android:textColor="#000000" android:textSize="15sp" android:ellipsize="marquee" android:scrollHorizontally="true" android:textStyle="bold"/> <LinearLayout android:layout_width="wrap_content" android:layout_height="fill_parent"> <TextView android:id="@+id/ramkingList" android:layout_width="wrap_content" android:layout_height="fill_parent" android:text="@string/rankinglist" android:textColor="#000000" android:textSize="14sp" /> <TextView android:id="@+id/rankinglist" android:layout_width="wrap_content" android:layout_height="fill_parent" android:text="@string/rankingexample" android:textColor="#000000" android:textSize="14sp" /> </LinearLayout> </LinearLayout> </LinearLayout>
userList est nul .... AsyncTask.execute ne pas attendre que le travail est fait ... ok – Selvin
qui est le problème, je l'ai déjà mis la AsyncTask dans la méthode onCreate() dans la classe LikeFragmentList et ensuite appelé 'adapterLike = new BoostAdapter (ctx, userList);' afin de peupler la listview avec quelque chose, mais apparemment ce n'est pas suffisant. J'ai essayé de laisser l'asynctask dans onCreate() et déplacez 'adapterLike = new BoostAdapter (ctx, userList);' dans le onActivityCreated. Mais il renvoie la même erreur. Quelque chose ne va pas avec le code AsyncTask? – UserK