【问题标题】:Button in ListFragment - App crashes on clickListFragment 中的按钮 - 单击时应用程序崩溃
【发布时间】:2016-09-27 11:59:38
【问题描述】:

应用程序打开正常,第一个 Fragment 正确显示。滑动时,屏幕上会出现下一个 fragment 布局。在那里,单击按钮时,应用程序崩溃。

我得到的错误是:

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference

错误堆栈中的一些顶部条目如下:

at android.widget.ArrayAdapter.createViewFromResource(ArrayAdapter.java:401)

at android.widget.ArrayAdapter.getView(ArrayAdapter.java:369)

at android.widget.AbsListView.obtainView(AbsListView.java:2346)

at android.widget.ListView.makeAndAddView(ListView.java:1876)

at android.widget.ListView.fillDown(ListView.java:702)

at android.widget.ListView.fillFromTop(ListView.java:763)

at android.widget.ListView.layoutChildren(ListView.java:1685)

at android.widget.AbsListView.onLayout(AbsListView.java:2148)

at android.view.View.layout(View.java:16636)

at android.view.ViewGroup.layout(ViewGroup.java:5437)

应用的main activity如下:

public class MainActivity extends FragmentActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ViewPager pager = (ViewPager) findViewById(R.id.viewPager);
    pager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
}

private class MyPagerAdapter extends FragmentPagerAdapter {

    public MyPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        switch(position) {

            case 0: return FirstFragment.newInstance("FirstFragment, Instance 1");
            case 1: return SecondFragment.newInstance("SecondFragment, Instance 1");
            default: return FirstFragment.newInstance("FirstFragment, Default");
        }
    }

}
}

SecondFragment.java 如下:

public class SecondFragment extends ListFragment {

static public ArrayAdapter<String> adapter;
static String[] values = new String[3]; 

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.second_frag, container,
            false);

    final Button btn = (Button) rootView.findViewById(R.id.readWebpage);
    if (btn != null) {
        btn.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v){
                new HttpGetReq().execute("http://xxx.xxx.xxx.xxx");
                adapter = new ArrayAdapter<String>(getActivity(),
                        android.R.layout.simple_list_item_1, values);
                setListAdapter(adapter);
            }
        });
    }
    return rootView;
}

public static SecondFragment newInstance(String text) {

    SecondFragment f = new SecondFragment();
    Bundle b = new Bundle();
    b.putString("msg", text);
    f.setArguments(b);

    return f;
}


 }

单击按钮时,HttpGetReq.java 工作类从服务器获取数据并将其显示到列表中。

public class HttpGetReq extends AsyncTask<String , Void ,String> {
String server_response;

@Override
protected String doInBackground(String... strings) {

    URL url;
    HttpURLConnection urlConnection = null;

    try {
        url = new URL(strings[0]);
        urlConnection = (HttpURLConnection) url.openConnection();

        int responseCode = urlConnection.getResponseCode();

        if(responseCode == HttpURLConnection.HTTP_OK){
            server_response = readStream(urlConnection.getInputStream());
        }
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

@Override
protected void onPostExecute(String s) {
    super.onPostExecute(s);
    Log.i("TAG", "Assigning new value");
   SecondFragment.values[1] = server_response;
}

// Converting InputStream to String
private String readStream(InputStream in) {
    BufferedReader reader = null;
    StringBuffer response = new StringBuffer();
    try {
        reader = new BufferedReader(new InputStreamReader(in));
        String line = "";
        while ((line = reader.readLine()) != null) {
            response.append(line);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (reader != null) {
            try {
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    return response.toString();
}
}

second_Frag.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"
    android:id="@+id/myView2">>
    <Button
        android:id="@+id/readWebpage"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="onClick"
        android:text="Refresh"
        android:layout_gravity="center_horizontal">
    </Button>
    <ListView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@id/android:list"
        android:background="@color/background_Color"
        android:layout_width="fill_parent"
        android:gravity="center"
        android:layout_height="fill_parent"/>
</LinearLayout>

【问题讨论】:

  • 请提供日志
  • 什么是错误,你得到了
  • 您正在尝试将值设置为静态数组。第一手是不允许的。跟踪您的错误并找到根本原因并将其发布,这可能会有所帮助。
  • 已编辑问题以包含错误日志。

标签: android listview android-fragments android-arrayadapter


【解决方案1】:
new HttpGetReq().execute("http://xxx.xxx.xxx.xxx");
adapter = new ArrayAdapter<String>(getActivity(),
        android.R.layout.simple_list_item_1, values);
setListAdapter(adapter);

在这里,您在从 HttpGetReq 获取数据之前设置适配器。由于 HttpGetReq 是一个 AsyncTask,因此它会在您调用 execute 后立即执行该行,并将您的值数组保持为空。从 HttpGetReq 的onPostExecute 获取数据后,您应该在适配器中设置数据。

@Override
protected void onPostExecute(String s) {
    super.onPostExecute(s);
    Log.i("TAG", "Assigning new value");
    SecondFragment.values[1] = server_response;

    // Set your data here 

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-24
    • 2017-07-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多