我正在尝试使用viewpager和两个标签实现一个活动,以便允许各节之间的滑动手势,每个节包含一个带有自定义适配器的列表视图,该适配器从异步任务中加载数据。我想在加载数据时显示加载微调器。
如果我们使用普通的listview和一个简单的适配器,它就可以工作。当我们为listviews引入自定义适配器时会出现问题。 Eclipse返回以下错误:
致命的例外:主要 显示java.lang.NullPointerException at libraries.BoostAdapter.getCount(BoostAdapter.java:58) 在android.widget.ListView.setAdapter(ListView.java:466) at 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>
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>
答案 0 :(得分:0)
我不知道您的问题是否已解决,但是,我遇到了同样的问题,并在此处提出了解决方案: 问题是主线程比次线程(或asyncktask)运行得更快,那么我们必须确保当我们创建list.setAdapter()时,我们的用户列表包含数据。 例如,将这行代码放在“onPostExecute”AsyncTask中。 在你的情况下:
onPostExecute(anyObject){
adapterLike = new BoostAdapter(ctx, userList);
listv.setAdapter(adapterLike);
}