android - 从 dialogfragment 发布新数据后更新 Listview

标签 android listview android-listview android-asynctask android-dialogfragment

我尝试在从 DialogFragment 提交新数据后直接更新我的 listview。 但是,当我调用 notifyDataSetChanged() 时,它会给我一个 NullPointerException 并且我的应用程序已关闭。

这就是我想要的场景

enter image description here

这是我的代码

我用来从服务器获取数据的这个 Activity

public class LayoutActivity extends Fragment {

    private ListView listview;
    private ListItemAdapter theAdapter;
    String URL = "http://localhost/api/question/get_newest_except/0/0/15";
    ProgressDialog pDialog;
    NodeList nodelist;

    public LayoutActivity() {
        super();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootview = inflater.inflate(R.layout.layout_main, container,false);
        DownloadXML a = new DownloadXML(this);
        a.execute(URL);

        listview = (ListView) rootview.findViewById(R.id.list01);

        return rootview;
    }

    public class DownloadXML extends AsyncTask<String, Void, Void>{

        private LayoutActivity aku;
        ArrayList<ListItemObject> data;

        public DownloadXML(LayoutActivity aku) {
            super();
            this.aku = aku;
        }

        @Override
        protected void onPreExecute() {
            pDialog = new ProgressDialog(getActivity());
            pDialog.setMessage("Loading...");
            pDialog.setIndeterminate(false);
            pDialog.show();
        }

        @Override
        protected void onPostExecute(Void result) {
            // TODO Auto-generated method stub
            data = new ArrayList<ListItemObject>();
            ListItemObject itemData;

            try{
                for (int temp = 0; temp < nodelist.getLength(); temp++) {
                    Node nNode = nodelist.item(temp);
                    if (nNode.getNodeType() == Node.ELEMENT_NODE) {
                        Element eElement = (Element) nNode;
                        itemData = new ListItemObject();

                        itemData.setId(getNode("pb__question__id",eElement));
                        itemData.setOwner(getNode("pb__question__consumer__id",eElement));
                        if(!getNode("pb__question__consumer__id",eElement).equalsIgnoreCase("0")){
                            itemData.setName(getNode("pb__question__consumer__name",eElement));
                            itemData.setJob(getNode("pb__question__consumer__occupation", eElement));
                            itemData.setProfilePic(getNode("pb__question__consumer__pp",eElement));
                        }
                        itemData.setStatus(getNode("pb__question__title",eElement));
                        itemData.setExtras(getNode("pb__question__topic__name", eElement));
                        if(!getNode("att__pict",eElement).isEmpty()){
                            itemData.setImage(getNode("att__pict", eElement));
                        }

                        if(getNode("pb__question__type", eElement).equalsIgnoreCase("1")){
                            itemData.setOpini(getNode("pb__question__total__opini", eElement));
                        }else if(getNode("pb__question__type", eElement).equalsIgnoreCase("2") || getNode("pb__question__type", eElement).equalsIgnoreCase("3")){
                            itemData.setOpini(getNode("pb__question__total__polling", eElement));
                        }else if(getNode("pb__question__type", eElement).equalsIgnoreCase("4")){
                            itemData.setOpini(getNode("pb__question__total__rating", eElement));
                        }

                        itemData.setTipe(getNode("pb__question__type", eElement));
                        itemData.setIkuti(getNode("pb__question__total__follow", eElement));
                        itemData.setSebarkan(getNode("pb__question__total__share", eElement));

                        data.add(itemData);
                    }
                }

                theAdapter = new ListItemAdapter(aku.getActivity(),data);
                listview.setAdapter(theAdapter);

            }catch(Exception e){
                Toast.makeText(getActivity(), "Koneksi dengan server gagal", Toast.LENGTH_SHORT).show();
            }

            pDialog.dismiss();
        }

        @Override
        protected Void doInBackground(String... Url) {
            // TODO Auto-generated method stub
            try {
                URL url = new URL(Url[0]);
                DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
                DocumentBuilder db = dbf.newDocumentBuilder();
                Document doc = db.parse(new InputSource(url.openStream()));
                doc.getDocumentElement().normalize();
                nodelist = doc.getElementsByTagName("pb__question");
            } catch (Exception e) {
                Log.e("Error", e.getMessage());
                e.printStackTrace();
            }
            return null;
        }

    }

    private static String getNode(String sTag, Element eElement) {
        NodeList nlList = eElement.getElementsByTagName(sTag).item(0).getChildNodes();
        Node nValue = (Node) nlList.item(0);
        String result = "";
        if(nValue!=null){
            result = nValue.getNodeValue();
        }
        return result;
    }
}

这是 listview 适配器,在这个适配器中,我从每个项目调用 Dialog

public class ListItemAdapter extends BaseAdapter{

    private ArrayList<ListItemObject> itemCards;
    private Context mContext;
    private FragmentManager mFragmentManager;
    ImageLoader imageLoader = AppController.getInstance().getImageLoader();

    public ListItemAdapter(FragmentActivity fa, ArrayList<ListItemObject> d) {
        super();
        this.mContext = fa;
        this.itemCards= d;
        mFragmentManager = fa.getSupportFragmentManager();
    }

    @Override
    public int getCount() {
        return itemCards.size();
    }

    @Override
    public Object getItem(int pos) {
        return itemCards.get(pos);
    }

    @Override
    public long getItemId(int pos) {
        return pos;
    }

    @Override
    public View getView(final int position, View convertview, ViewGroup parent) {
        // TODO Auto-generated method stub
        View row=null;

        row = convertview;
        row = View.inflate(mContext, R.layout.item_layout, null);

        final boolean[] mHighlightedPositions = new boolean[itemCards.size()];

        if (imageLoader == null)
            imageLoader = AppController.getInstance().getImageLoader();
        LinearLayout containerPP = (LinearLayout) row.findViewById(R.id.idCon);
        NetworkImageViewCircle fotoPP = (NetworkImageViewCircle) row.findViewById(R.id.pp);
        TextView nama = (TextView) row.findViewById(R.id.name);
        TextView kerjaan = (TextView) row.findViewById(R.id.jobs);

        NetworkImageView gambar = (NetworkImageView) row.findViewById(R.id.feedImage1);

        TextView status = (TextView) row.findViewById(R.id.txtStatusMsg);
        TextView extra = (TextView) row.findViewById(R.id.txtUrl);

        TextView opinion = (TextView) row.findViewById(R.id.opini);
        TextView follow = (TextView) row.findViewById(R.id.ikuti);
        TextView share = (TextView) row.findViewById(R.id.sebarkan);

        Button Opini = (Button) row.findViewById(R.id.Button01);
        Button Ikuti = (Button) row.findViewById(R.id.Button02);
        Button Sebarkan = (Button) row.findViewById(R.id.Button03);
        Ikuti.setTag(position);
        Opini.setTag(position);

        ListItemObject item = itemCards.get(position);

        if(item.getName()==null){
            containerPP.setVisibility(View.GONE);
        }

        if(item.getExtras().equalsIgnoreCase("Pertanyaan Pengguna")){
            extra.setVisibility(View.GONE);
        }

        if(item.getImage()==null){
            gambar.setVisibility(View.GONE);
        }

        if(item.getTipe().equals("4")){
            opinion.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.star_icon, 0);
        }else if(item.getTipe().equals("2") || item.getTipe().equals("3")){
            opinion.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.poll_icon, 0);
        }

        nama.setText(item.getName());
        kerjaan.setText(item.getJob());
        fotoPP.setImageUrl(item.getProfilePic(), imageLoader);
        status.setText(item.getStatus());
        extra.setText(item.getExtras().replaceAll("\n",""));
        opinion.setText(item.getOpini());
        follow.setText(item.getIkuti());
        share.setText(item.getSebarkan());
        gambar.setImageUrl(item.getImage(), imageLoader);

        if(mHighlightedPositions[position]) {
            Ikuti.setBackgroundResource(R.color.ijo);
            Ikuti.setTextColor(Color.WHITE);
        }else{
            Ikuti.setBackgroundResource(R.color.abu2);
            Ikuti.setTextColor(Color.BLACK);
        }

        Opini.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                AddKomentar(v,position);
            }
        });

        Ikuti.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            }
        });

        Sebarkan.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            }
        });

        return row;
    }

    public void AddKomentar(View v,int pos){
        FragmentActivity activity = (FragmentActivity)(mContext);
        FragmentManager fm = activity.getSupportFragmentManager();
        ListItemObject item = itemCards.get(pos);

        DialogAddOpini dialog = new DialogAddOpini();
        Bundle args = new Bundle();
        args.putString("question",item.getId());
        args.putString("owner",item.getOwner());
        dialog.setArguments(args);

        dialog.show(fm, "Dialog");
    }
}

这是DialogFragment

public class DialogAddOpini extends DialogFragment{

    ListItemAdapter theAdapter;
    String question_id,owner_id;
    EditText question_field;
    ProgressDialog pDialog;

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        LayoutInflater inflater = getActivity().getLayoutInflater();
        final View dialogView = inflater.inflate(R.layout.addopini, null);

        Bundle mArgs = getArguments();
        question_id = mArgs.getString("question");
        owner_id = mArgs.getString("owner");

        builder.setTitle("Tambahkan Opini");
        builder.setView(dialogView)
        .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
            }
        })
        .setPositiveButton(R.string.okay, new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                 question_field = (EditText) dialogView.findViewById(R.id.content);
                 SendComment send = new SendComment();
                 send.execute(question_field.getText().toString());

            }
        });
        Dialog dialog = builder.create();
        return dialog;
    }


    private class SendComment extends AsyncTask<String, Void, Void>{

        public SendComment() {
            super();
        }

        @Override
        protected void onPreExecute() {
            pDialog = new ProgressDialog(getActivity());
            pDialog.setMessage("Submitting...");
            pDialog.setIndeterminate(false);
            pDialog.show();
        }

        @Override
        protected Void doInBackground(String... params) {
            String content = params[0];
            postData(content);
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            theAdapter.notifyDataSetChanged();
            pDialog.dismiss();
        }

    }

    public void postData(String content) {
        HttpClient httpclient = new DefaultHttpClient();
        HttpPost httppost = new HttpPost("http://localhost/api/opini/add");

            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
            nameValuePairs.add(new BasicNameValuePair("pb_question_id", question_id));
            nameValuePairs.add(new BasicNameValuePair("owner_id", owner_id));
            nameValuePairs.add(new BasicNameValuePair("opini_text", content));
            nameValuePairs.add(new BasicNameValuePair("is_anonym", "1"));

            try {
                httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            try {
                HttpResponse response = httpclient.execute(httppost);
                Log.d("Http Response:", response.toString());
            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
    } 
}

我在 DialogFragment 内的 onPostExecute 内调用了 notifyDataSetChanged(),但它给了我 NullPointerException。 谁能帮帮我?

这是日志

enter image description here

谢谢

最佳答案

theAdapter 未在类 DialogAddOpini 中初始化,您需要在 OnPostExecute 中使用它之前对其进行初始化。

我更愿意使用 Listener 从 DialogFragment 返回数据并只更新 Adapter 中的 List。

public class DialogAddOpini extends DialogFragment {  

private Listener mListener;

public void setListener(Listener listener) {
  mListener = listener;  
}

static interface Listener {
    void returnData();
}

创建对话框时设置监听器:

 public void AddKomentar(View v,int pos){
        FragmentActivity activity = (FragmentActivity)(mContext);
        FragmentManager fm = activity.getSupportFragmentManager();
        ListItemObject item = itemCards.get(pos);

        DialogAddOpini dialog = new DialogAddOpini();
        Bundle args = new Bundle();
        args.putString("question",item.getId());
        args.putString("owner",item.getOwner());
        dialog.setArguments(args);

        dialog.setListener(this);
        dialog.show(fm, "Dialog");
    }

并返回如下数据:

 @Override
  protected void onPostExecute(Void result) {
      if (mListener != null) {
                 mListener.returnData();
        }

       pDialog.dismiss();
   }

并覆盖 Adapter 中的 returnData 并更新列表:

public class ListItemAdapter extends BaseAdapter implements DialogAddOpini.Listener {

   @Override
   public void returnData() {

         notifyDataSetChanged();
   }
}

更新:

您必须传递数据并将其设置在 Adapter 的 Arraylist 中以反射(reflect)更改。 在显示对话框时跟踪位置:

 Integer selected_position =-1 ;
  public void AddKomentar(View v,int pos){
            FragmentActivity activity = (FragmentActivity)(mContext);
            FragmentManager fm = activity.getSupportFragmentManager();
            ListItemObject item = itemCards.get(pos);

            DialogAddOpini dialog = new DialogAddOpini();
            Bundle args = new Bundle();
            args.putString("question",item.getId());
            args.putString("owner",item.getOwner());
            dialog.setArguments(args);
            selected_position = pos;
            dialog.setListener(this);
            dialog.show(fm, "Dialog");
        }

    @Override
       public void returnData( String counter) {
             itemCards.get(selected_position).setOpini(counter);
             notifyDataSetChanged();
             selected_position=-1;
       }

希望能帮到你

关于android - 从 dialogfragment 发布新数据后更新 Listview,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27221758/

相关文章:

java - Android - 自定义 ListView 的输出值 - 出现错误

java - Xml 文件图像覆盖图像

android - GoogleAccountCredential 重用授权 - Google 云端硬盘

java - 安卓 ListView : how to change background color of specific cells (by index)?

java - Android:带有左侧状态行的 ListView

android - RecyclerView + Glide 显示结果一团糟

android - 使用 SimpleCursorAdapter 和 ViewBinder 在 ListView 项中设置图像

Android:如何使用自定义音轨录制视频?

android - 如何从Android市场删除.apk文件?

android - 为什么Activity重启后ArrayAdapter无法更新listview?