片段在android

时间:2016-10-23 09:59:37

标签: java android json android-asynctask

我使用Activity通过AsyncTask从json加载数据并在Fragment类中显示。 显示内容包括:ImageView,TextView,TextView以及当用户点击某个项目时会重定向GridView中相应的项目

在ManufactureFragment中包括:

  1. POJO ManufacturerItem
  2. LoadAllManufacturers扩展AsyncTask以从json
  3. 加载数据
  4. 适配器:从json调用加载数据
  5. 我的片段:

    public class ManufacturerFragment extends Fragment {
    
    ProgressDialog pDialog;
    JSONParser jsonParser = new JSONParser();
    
    
    // initiliaze adapter variable
    MyAdapter adapter; 
    JSONArray manufacturers = null;
    
    // manufacturers JSON url
    private static final String URL_MANUFACTURERS = "http://MYURL";
    
    public ManufacturerFragment() {
        // Required empty public constructor
    }
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.gridview_manufacturer, container, false);
    
        GridView gridView = (GridView) view.findViewById(R.id.gridview);
        // gridView.setAdapter(new MyAdapter(getActivity(), manufacturersList));
        adapter = new MyAdapter(getActivity(), manufacturersList);
        gridView.setAdapter(adapter);
    
        gridView.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> arg0, View view, int arg2, long arg3) {
                // on selecting a single manufacturer
                // CategoryCarActivity will be launched to show category car inside the manufacturer
                Intent i = new Intent(getActivity(), CategoryCarActivity.class);
    
                // send manufacturer id to activity to get list of cars under that manufacturer
                String manufacturer_id = ((TextView) view.findViewById(R.id.manufacturer_id)).getText().toString();
                i.putExtra("manufacturer_id", manufacturer_id);
    
                startActivity(i);
            }
        });
    
        return view;
    }
    
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onActivityCreated(savedInstanceState);
    
        new LoadAllManufacturers().execute();
    }
    
    
    class LoadAllManufacturers extends AsyncTask<String, String, String> {
        /**
         * Before starting background thread Show Progress Dialog
         * */
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            pDialog = new ProgressDialog(getActivity());
            pDialog.setMessage("Loading manufacturers. Please wait...");
            pDialog.setIndeterminate(false);
            pDialog.setCancelable(false);
            pDialog.show();
        }
    
        /**
         * After completing background task Dismiss the progress dialog
         * **/
        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
    
            adapter.notifyDataSetChanged();
            // dismiss the dialog after getting all manufacturers
            if (pDialog.isShowing())
                pDialog.dismiss();
        }
    }
    
    private class MyAdapter extends BaseAdapter
    {
        LayoutInflater inflater;
        Context context;
    
        public MyAdapter(Context context, ArrayList<HashMap<String, String>> arrayList)
        {
            this.context = context;
            this.manufacturersList = arrayList;
            this.inflater = LayoutInflater.from(context);
        }
    
        @Override
        public int getCount() {
            if (manufacturersList != null)
                return manufacturersList.size();
            return 0;
        }
    
        @Override
        public Object getItem(int i)
        {
            if (manufacturersList != null)
                return manufacturersList.get(i);
            return null;
        }
    
        @Override
        public long getItemId(int i)
        {
            if (manufacturersList != null)
                return manufacturersList.get(i).hashCode();
            return 0;
        }
    
        @Override
        public View getView(int i, View view, ViewGroup viewGroup)
        {
            View v = view;
            ImageView picture;
            TextView name;
    
            if(v == null)
            {
                v = inflater.inflate(R.layout.gridview_item, viewGroup, false);
                v.setTag(R.id.picture, v.findViewById(R.id.picture));
                v.setTag(R.id.text, v.findViewById(R.id.text));
            }
    
            picture = (ImageView)v.getTag(R.id.picture);
            name = (TextView)v.getTag(R.id.text);   
    
            picture.setImageResource(item.drawableId);
            name.setText(item.name);
    
            return v;
        }
       }
     }
    

    我的list_item_manufacturers.xml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
    
    <!-- Manufacturer_id / Hidden by default -->
    <TextView
        android:id="@+id/manufacturer_id"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:visibility="gone" />
    
    <!-- Manufacturer_name -->
    <TextView
        android:id="@+id/manufacturer_name"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="16dip"
        android:textColor="#000000"
        android:paddingTop="15dip"
        android:paddingBottom="15dip"
        android:paddingLeft="10dip"
        android:textStyle="bold"/>
    
    <!-- Logo image -->
    <ImageView
        android:id="@+id/iconName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:background="#000000"
        android:padding="1dp" />
     </RelativeLayout>
    

    我的gridview_manufacturer.xml

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <GridView
        android:id="@+id/gridview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:verticalSpacing="0dp"
        android:horizontalSpacing="0dp"
        android:stretchMode="columnWidth"
        android:numColumns="2" />
    </FrameLayout>
    

    当我调试和构建时,我看到json加载成功,但是然后它在行发生异常: logcat的:

    E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
                  Process: com.totoroads.android.app, PID: 3723
                  java.lang.RuntimeException: An error occurred while executing doInBackground()
                      at android.os.AsyncTask$3.done(AsyncTask.java:309)
                      at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
                      at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
                      at java.util.concurrent.FutureTask.run(FutureTask.java:242)
                      at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
                      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
                      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
                      at java.lang.Thread.run(Thread.java:818)
                   Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.util.ArrayList.add(java.lang.Object)' on a null object reference
                      at com.totoroads.android.app.FeedBackFragment$LoadAllManufacturers.doInBackground(ManufacturerFragment.java:136)
                      at com.totoroads.android.app.FeedBackFragment$LoadAllManufacturers.doInBackground(ManufacturerFragment.java:89)
                      at android.os.AsyncTask$2.call(AsyncTask.java:295)
                      at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                      at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) 
                      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
                      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
                      at java.lang.Thread.run(Thread.java:818)  
    

    Logcat中的最终异常:

    E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.totoroads.android.app, PID: 5730
                  java.lang.ClassCastException: java.util.HashMap cannot be cast to com.totoroads.android.app.ManufacturerFragment$MyAdapter$ManufacturerItem
                      at com.totoroads.android.app.ManufacturerFragment$MyAdapter.getView(FeedBackFragment.java:226)
                      at android.widget.AbsListView.obtainView(AbsListView.java:2346)
                      at android.widget.GridView.onMeasure(GridView.java:1065)
                      at android.view.View.measure(View.java:18788)
                      at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
    

    在线:

    ManufacturerFragment.MyAdapter.ManufacturerItem item = (ManufacturerFragment.MyAdapter.ManufacturerItem)getItem(i);
    

    有些错误我无法检测到它,如何修复此异常

    非常感谢!!

2 个答案:

答案 0 :(得分:1)

在致电ArrayList之前,您没有初始化AsyncTask。在执行AsyncTask中的onActivityCreated()之前添加此行:

manufacturersList = new ArrayList<>();

编辑1: 将适配器分配给变量:

adapter = new MyAdapter(getActivity(), manufacturersList);
gridView.setAdapter(adapter);

因为现在您正在使用更改通知空适配器。

编辑2: 您的代码永远不会输入onPostExecute,因为您没有覆盖AsyncTask的{​​{1}}方法。您的onPostExecute初始化为AsyncTask,因此AsyncTask<String, String, String>的参数应为onPostExecute,而不是String

Void

编辑3: 这是您可以从@Override protected void onPostExecute(String s) { super.onPostExecute(s); adapter.notifyDataSetChanged(); // dismiss the dialog after getting all manufacturers if (pDialog.isShowing()) pDialog.dismiss(); } 方法开始的一个工作示例:

getView

答案 1 :(得分:0)

我只编写代码中的更改以及它上面和下面的行。

更改

  1. 您的ArrayListnull。 Ininialize。
  2. 为适配器创建变量,因为您需要调用 notifyDataSetChanged上的onPostExecute {/ 1}}。

  3. // manufacturers JSON url
    private static final String URL_MANUFACTURERS = "http://MYURL";
    
    MyAdapter adapter;
    ArrayList<HashMap<String, String>> manufacturersList = new ArrayList<>();
    
    public ManufacturerFragment() {
        // Required empty public constructor
    }
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        ...
    
        // initialize the adapter
        adapter = new MyAdapter(getActivity(), manufacturersList)
        GridView gridView = (GridView) view.findViewById(R.id.gridview);
        gridView.setAdapter(adapter);
    
        ...
    }
    
    
    class LoadAllManufacturers extends AsyncTask<String, String, String> {
    
        /**
         * After completing background task Dismiss the progress dialog
         * **/
        protected void onPostExecute(Void args) {
    
            // notify the adapter
            adapter.notifyDataSetChanged();
    
            // dismiss the dialog after getting all manufacturers
            ...
        }
    }