Как реализовать listview с фрагментом, пользовательским адаптером, вкладками и просмотрщиком в Android

Я пытаюсь реализовать действие с просмотрщиком и двумя вкладками, чтобы разрешить жесты пролистывания между разделами, каждый из которых содержит список с пользовательским адаптером, который загружает данные из асинхронной задачи. Я хотел бы показать счетчик загрузки при загрузке данных.

Если мы используем обычный список с простым адаптером, он работает. Проблема возникает, когда мы вводим собственный адаптер для списков. Eclipse возвращает следующую ошибку:

НЕИСПРАВНОЕ ИСКЛЮЧЕНИЕ: основное java.lang.NullPointerException в библиотеках.BoostAdapter.getCount(BoostAdapter.java:58) в android.widget.ListView.setAdapter(ListView.java:466) в kasuga.gamble.roma.LikeAttendList$AppSectionsPagerAdapter$LikeFragmentList. onActivityCreated(LikeAttendList.java:237) в android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:891) в android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1080) в android.support .v4.app.BackStackRecord.run(BackStackRecord.java:622) [...]

Любые советы будут приветствоваться! Спасибо.

  • Активность (для простоты рассмотрим только один 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 создан:

    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;
    }
          }

Это требуемый xml:

  • список избранных
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:listSelector="@drawable/list_selector"/>

    <ProgressBar android:id="@+id/loading_spinner_like"
        style="?android:progressBarStyleLarge"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center" />

</LinearLayout>
  • attllike.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" />
    
  • присутствовать

<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>

person UserK    schedule 31.05.2013    source источник
comment
userList имеет значение null .... AsyncTask.execute не ждет, пока задание будет выполнено ...   -  person Selvin    schedule 31.05.2013
comment
Хорошо, в этом проблема, я уже поместил асинхронную задачу в метод onCreate() в классе LikeFragmentList, а затем вызвал adapterLike = new BoostAdapter(ctx, userList);, чтобы чем-то заполнить список, но, видимо, этого недостаточно. Я пытался оставить асинхронную задачу в onCreate() и переместить adapterLike = new BoostAdapter(ctx, userList); в onActivityCreated. Но он возвращает ту же ошибку. Что-то не так с кодом AsyncTask?   -  person UserK    schedule 31.05.2013


Ответы (1)


Я не знаю, была ли ваша проблема решена, однако у меня была та же проблема, и я привожу решение здесь: проблема в том, что основной поток работает быстрее, чем вторичный поток (или asyncktask), поэтому мы должны убедиться, что когда мы делаем list.setAdapter() наш список пользователей содержит данные. Например, поместив эту строку кода в "onPostExecute" AsyncTask. В твоем случае:

onPostExecute(anyObject){
    adapterLike = new BoostAdapter(ctx, userList);
    listv.setAdapter(adapterLike);
}
person Miguel    schedule 29.04.2015