【问题标题】:Fragment in Activity is gets context null in setAdapter for ListViewActivity 中的片段在 ListView 的 setAdapter 中获取上下文 null
【发布时间】:2014-06-24 19:53:56
【问题描述】:

实际上,自从我开始开发此应用程序以来,我一直有这个问题 3 个月。我已经阅读了这个网站上的数百篇文章,在其他网站上,我已经阅读了教程,但我还没有找到解决方案。 我认为这个问题与我拥有应用程序结构的方式有关

我正在开发一个显示多个部分的应用程序,每个部分是一个片段,主要活动使用 ViewPager 一次显示一个片段(如 fb 应用程序或 twitter 应用程序)。每个部分都将显示具有不同信息的列表视图:新闻、视频、分类广告等。一旦显示了一个部分,比如说新闻部分,它就会显示一个带有文章/新闻的列表视图。问题是当我尝试显示列表视图时,因为在我用来显示列表视图的适配器中,setAdapter 行中给了我 NullPointerException。

我找到了给我异常的行,实际上是context 声明。即使在我所有的片段中上下文都是空的(我不知道为什么),我仍然可以显示列表视图,但在其他一些情况下,应用程序崩溃并给出了 NPE。我通过Context context=getActivity() 获取上下文,但是当我测试它时它给了我null。

这是我成功显示列表视图的片段之一

public class HomeActivity extends Fragment{
   static ListView newsList;
   static Item item=null;
   Context context=getActivity();
   ItemAdapter itemAdapter;
   List<Item> news=new ArrayList<Item>();
   static int i=0;
   static Activity activity;
   static String HOME_FRAGMENT="NEWS";
   public static final int TIME_ENTRY_REQUEST_CODE=1;
   FragmentManager fm;


public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState){
   super.onCreateView(inflater, container, savedInstanceState);
   View view=inflater.inflate(R.layout.home_activity, container,false);
   newsList=(ListView)view.findViewById(R.id.newslist);
   setRetainInstance(true); 
   return view;
}

public void onAttach(Activity activity){
    super.onAttach(activity);
    HomeActivity.activity=activity;
}

public void onSaveInstanceState(Bundle outState){
    super.onSaveInstanceState(outState);
}

public void displayNews(final List<Item> news){
    try {        
         if(news==null || news.size()==0){
                //Retrieve again the data list
         }
         Log.d("HomeActivity","total news: "+news.size());
     } catch (Exception e) {
         e.printStackTrace();
     }
    if(context==null){
         Log.d("HomeActivity","context null!");
    }
    itemAdapter=new ItemAdapter(context,(ArrayList<Item>) news);
    newsList.setAdapter(itemAdapter);
}   

}

更新:这是我获得 NPE 的另一个片段,

public class VideosActivity extends Fragment{

ListView listvideo;
ItemAdapter itemAdapter;
Context context;
Activity activity;
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState){
       super.onCreateView(inflater, container, savedInstanceState);
       View view=inflater.inflate(R.layout.videos_activity, container,false);
       listvideo=(ListView)view.findViewById(R.id.videoslist);
       Log.d("videos activity","onCreateView ready!!");
               context=getActivity();
       setRetainInstance(true); 
       return view;
    }


public void onAttach(Activity activity){
    super.onAttach(activity);
    this.activity=activity;
}

public void displayVideos(final List<Item> videos){
    try {        
         if(videos==null || videos.size()==0){
                //Retrieve again the data list

         }
     } catch (Exception e) {
         e.printStackTrace();
     }
    for(int i=0;i<videos.size();i++){

    }
    itemAdapter=new ItemAdapter(activity,(ArrayList<Item>) videos);//I also used context in this line, but I still get the NPE
    listvideo.setAdapter(itemAdapter); //Here's the line that gives me the NPE
}   

}

我正在解析 XML 中的所有信息,并通过 AsyncTask 管理所有内容
这是我的适配器

public class ItemAdapter extends BaseAdapter implements OnItemClickListener{
    Item item=new Item();
    private ArrayList<Item> news=new ArrayList<Item>();
    private static final int NO_PICTURE_VIEW=0;
    private static final int PICTURE_VIEW=1;

    public ItemAdapter(Context context,ArrayList<Item> items) {
    super();
    news.addAll(items);
    }
    public int getCount() {
    // TODO Auto-generated method stub
    return news.size();
}

    public Item getItem(int index) {
    // TODO Auto-generated method stub
    return getItem(index);
}

    public long getItemId(int index) {
    // TODO Auto-generated method stub
    return index;
}

    public int getViewTypeCount() {
         return 2;
}

    public int getItemViewType(int position) {
    Item article=news.get(position);      
        if(article.getImage()!=null)      
            return PICTURE_VIEW;
        else
                return NO_PICTURE_VIEW;
}
@Override
    public View getView(int index, View view, ViewGroup parent) {
    item=news.get(index);
    int type=getItemViewType(index);
    if(view==null){
            LayoutInflater inflater=LayoutInflater.from(parent.getContext());
        if(type==NO_PICTURE_VIEW){
        view=inflater.inflate(R.layout.item_no_picture_list,parent,false);
                TextView titleView=(TextView)view.findViewById(R.id.titleNoPicture);
        titleView.setText(item.getTitle());
        }
        else{
        view=inflater.inflate(R.layout.item_picture_list,parent,false);
        TextView titleView=(TextView)view.findViewById(R.id.titleArticle);
        ImageView image=(ImageView)view.findViewById(R.id.imageItem);
        titleView.setText(item.getTitle());
        image.setImageBitmap(item.getImage());
    }
}

return view;
}
}

这是主要活动

public class MainActivity extends FragmentActivity{
    private String tabs[]={"News","Sports","Valley Life","Videos","Classifieds","Directory","Weather"};
ViewPager viewPager=null;
FragmentManager fragmentManager=getSupportFragmentManager();
android.support.v4.app.FragmentTransaction ft=fragmentManager.beginTransaction();
    AdapterView adapterView;
static ParseManager parser=new ParseManager();
static List<Item> news=new ArrayList<Item>();
ArrayList<Item> sports=new ArrayList<Item>();
ArrayList<Item> valleyLife=new ArrayList<Item>();
public static final int TIME_ENTRY_REQUEST_CODE=1;
HomeActivity home;
JSONManager jmanager=new JSONManager();
WeatherManager weather=new WeatherManager();

    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    viewPager=(ViewPager)findViewById(R.id.pager);
    viewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener(){
                public void onPageSelected(int position)          
                getActionBar().setSelectedNavigationItem(position);
            }
    });
    viewPager.setAdapter(new AdapterView(fragmentManager));
    viewPager.setOffscreenPageLimit(tabs.length);
    adapterView=new AdapterView(getSupportFragmentManager());
    /*initialization of the action bar: color, icon & title.*/
    final android.app.ActionBar actionbar=getActionBar();
    ColorDrawable color=new ColorDrawable(Color.parseColor("#cd853f"));
    actionbar.setBackgroundDrawable(color);
    actionbar.setTitle("Title");
    ActionBar.TabListener tabListener=new ActionBar.TabListener() {
        public void onTabUnselected(Tab tab, FragmentTransaction ft) {

        }   


        @Override
        public void onTabSelected(Tab tab, FragmentTransaction ft) {
            viewPager.setCurrentItem(tab.getPosition());
            ft=getFragmentManager().beginTransaction();
            //ft.replace(layouts[tab.getPosition()], (adapterView.getItem(tab.getPosition()));
            ft.commit();

        }

        @Override
        public void onTabReselected(Tab tab, FragmentTransaction ft) {  

        }
    };
    /*Displaying Tabs for the app */
    for(int i=0;i<tabs.length;i++)  
        actionbar.addTab(actionbar.newTab().setText(tabs[i]).setTabListener(tabListener));
    actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
            viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
                @Override
                public void onPageSelected(int position) {
                actionbar.setSelectedNavigationItem(position);
            }

                @Override
                public void onPageScrolled(int arg0, float arg1, int arg2) {
            }
                @Override
                public void onPageScrollStateChanged(int arg0) {
            }
        });
        parser.execute();
        jmanager.execute();
        weather.execute();
        getApplicationContext();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

}

这是我的日志猫

FATAL EXCEPTION: main
java.lang.NullPointerException
at com.example.test23.VideosActivity.displayVideos(VideosActivity.java:54)
at com.example.test23.ParseManager.onPostExecute(ParseManager.java:52)
at com.example.test23.ParseManager.onPostExecute(ParseManager.java:1)
at android.os.AsyncTask.finish(AsyncTask.java:631)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5031)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:555)
at dalvik.system.NativeStart.main(Native Method)

更新:这是 video_activity.xml

<?xml version="1.0" encoding="utf-8"?>
    <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="@+id/videoslist"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" >
        </ListView>
     </LinearLayout>

我只是想知道我的应用出了什么问题以及为什么我的上下文为空,所以我可以继续我的应用的下一步,也许是结构、编程方式的问题,我不知道。任何帮助表示赞赏,如果您需要更多代码,请告诉我。

【问题讨论】:

  • 发布你的videos_activity.xml
  • @Rod_Algonquin 刚刚发布!

标签: android listview android-fragments android-asynctask fragment


【解决方案1】:

确保从该行中删除“=getActivity()”:

Context context=getActivity();

所以它只是写成:

Context context;

然后改变这个:

public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle        savedInstanceState){
   super.onCreateView(inflater, container, savedInstanceState);
   View view=inflater.inflate(R.layout.home_activity, container,false);
   newsList=(ListView)view.findViewById(R.id.newslist);
   setRetainInstance(true); 
   return view;
}

到这里:

public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle        savedInstanceState){
   super.onCreateView(inflater, container, savedInstanceState);
   View view=inflater.inflate(R.layout.home_activity, container,false);
   newsList=(ListView)view.findViewById(R.id.newslist);
   context = getActivity();  // <--- add this line here
   setRetainInstance(true); 
   return view;
}

【讨论】:

  • 我这样做了,但我仍然得到 NPE,我测试了它,但上下文仍然为空
  • 您是否更改了所有片段以使用上述方法?
  • 是的,在所有这些中,但我仍然收到 NPE
  • 你确定 itemAdapter 是 null 而不是 listVideo?
  • 我可以推荐的最好的方法是,在 displayVideos() 中,在 itemAdapter=new ItemAdapter(...) 之后,检查 itemAdapter != null,如果它不为 null,则只设置适配器。
【解决方案2】:

您只能在调用onAttach 后使用getActivity() 设置上下文,所以这样做

context = getActivity() 

在你的onCreateView

【讨论】:

  • 显示更新后的代码以及您在代码中遇到异常的位置
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-05
  • 1970-01-01
  • 2019-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多