问题
I am trying to update my listview
directly after I submit new data from DialogFragment
.
But when I call notifyDataSetChanged()
it give me an NullPointerException
and my app is close.
So this is the scenario what I want
And this is my code
This activity that I use to get data from the server
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;
}
}
and this is the listview
adapter, in this adapter I call Dialog
from each item
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");
}
}
and this is the 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();
}
}
}
I call notifyDataSetChanged()
inside onPostExecute
inside DialogFragment
, but it give me NullPointerException
.
Can anyone help me?
This the log
Thanks
回答1:
theAdapter
is not initialized in class DialogAddOpini
, You need to initialized it before using it in OnPostExecute
.
I will prefer to use Listener to return the data from DialogFragment
and update List in the Adapter only.
public class DialogAddOpini extends DialogFragment {
private Listener mListener;
public void setListener(Listener listener) {
mListener = listener;
}
static interface Listener {
void returnData();
}
Set the listener while creating Dialog :
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");
}
And return the data like :
@Override
protected void onPostExecute(Void result) {
if (mListener != null) {
mListener.returnData();
}
pDialog.dismiss();
}
And override returnData
in Adapter and update the list:
public class ListItemAdapter extends BaseAdapter implements DialogAddOpini.Listener {
@Override
public void returnData() {
notifyDataSetChanged();
}
}
Update :
You have to pass the data and set it in the Adapter's Arraylist to reflect the changes. Track the position while you show the dialog :
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;
}
Hope it helps ツ
来源:https://stackoverflow.com/questions/27221758/update-listview-after-post-new-data-from-dialogfragment