简体   繁体   English

ListView 不会使用 notifydatasetchanged 刷新

[英]ListView doesn't refresh with notifydatasetchanged

I have a MySQL database of two columns displayed in an android ListView .我有一个包含两列的 MySQL 数据库,显示在 android ListView I use Retrofit 1.9 to get the data from MySQL.我使用 Retrofit 1.9 从 MySQL 获取数据。 The adapter for the ListView is a BaseAdapter and I don't have a DatabaseHelper class. ListView的适配器是BaseAdapter ,我没有DatabaseHelper类。 When I add a data in the ListView from my mobile phone, it doesn't refresh the ListView .当我从手机在ListView添加数据时,它不会刷新ListView I have to close and restart the app.我必须关闭并重新启动应用程序。 I try to refresh with listViewAdapter.notifyDataSetChanged();我尝试使用listViewAdapter.notifyDataSetChanged();刷新listViewAdapter.notifyDataSetChanged(); . .

This is the fragment where the listview is:这是列表视图所在的片段:

public class rightFragment extends Fragment {

String BASE_URL = "http://awebsite.com";

View view;
ListView listView;
ListViewAdapter listViewAdapter;

Button buttondisplay;
Button buttonadd;
EditText new_id;
EditText newWordFra;
EditText newWordDeu;

ArrayList<String> id = new ArrayList<>();
ArrayList<String> fra = new ArrayList<>();
ArrayList<String> deu = new ArrayList<>();

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    view = inflater.inflate(com.example.geeko.Deu.R.layout.fragment_right, container, false);

    listView = (ListView) view.findViewById(com.example.geeko.Deu.R.id.listView); //<<<< ADDED NOTE use your id
    listViewAdapter = new ListViewAdapter(getActivity(), id, fra, deu);

    displayData();

    buttondisplay = (Button) view.findViewById(com.example.geeko.Deu.R.id.buttondisplay);
    buttonadd = (Button) view.findViewById(com.example.geeko.Deu.R.id.buttonadd);
    buttondelete = (Button) view.findViewById(com.example.geeko.Deu.R.id.newID);
    newWordFra = (EditText) view.findViewById(com.example.geeko.Deu.R.id.newWordFra);
    newWordDeu = (EditText) view.findViewById(com.example.geeko.Deu.R.id.newWordDeu);

    buttonadd.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            //Toast.makeText(MainActivity.this , "button add", Toast.LENGTH_LONG).show();
            insert_data();
           listViewAdapter.notifyDataSetChanged();

        }
    });

    buttondisplay.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            if (buttondisplay.getText().toString().contains("Show")) {
                listView.setAdapter(listViewAdapter);
                buttondisplay.setText("Hide");
            } else {
                listView.setAdapter(null);
                buttondisplay.setText("Show");
            }
        }
    });


    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long ids) {

            new_id.setText(id.get(position));
            newWordFra.setText(fra.get(position));
            newWordDeu.setText(deu.get(position));

        }
    });

    return view;

}

public void insert_data() {

    RestAdapter adapter = new RestAdapter.Builder()
            .setEndpoint(BASE_URL) //Setting the Root URL
            .build();

    AppConfig.insert api = adapter.create(AppConfig.insert.class);

    api.insertData(
            newWordFra.getText().toString(),
            newWordDeu.getText().toString(),
            new Callback<Response>() {
                @Override
                public void success(Response result, Response response) {

                    try {

                        BufferedReader reader = new BufferedReader(new InputStreamReader(result.getBody().in()));
                        String resp;
                        resp = reader.readLine();
                        Log.d("success", "" + resp);

                        JSONObject jObj = new JSONObject(resp);
                        int success = jObj.getInt("success");

                        if(success == 1){
                            Toast.makeText(getActivity(), "Successfully inserted", Toast.LENGTH_SHORT).show();
                        } else{
                            Toast.makeText(getActivity(), "Insertion Failed", Toast.LENGTH_SHORT).show();
                        }

                    } catch (IOException e) {
                        Log.d("Exception", e.toString());
                    } catch (JSONException e) {
                        Log.d("JsonException", e.toString());
                    }
                }

                @Override
                public void failure(RetrofitError error) {
                    Toast.makeText(getActivity(), error.toString(), Toast.LENGTH_LONG).show();
                }
            }
    );
}

public void displayData() {

    RestAdapter adapter = new RestAdapter.Builder()
            .setEndpoint(BASE_URL) //Setting the Root URL
            .build();

    AppConfig.read api = adapter.create(AppConfig.read.class);

    api.readData(new Callback<JsonElement>() {
                     @Override
                     public void success(JsonElement result, Response response) {

                         String myResponse = result.toString();
                         Log.d("response", "" + myResponse);

                         try {
                             JSONObject jObj = new JSONObject(myResponse);

                             int success = jObj.getInt("success");

                             if (success == 1) {

                                 JSONArray jsonArray = jObj.getJSONArray("details");
                                 for (int i = 0; i < jsonArray.length(); i++) {

                                     JSONObject jo = jsonArray.getJSONObject(i);

                                     id.add(jo.getString("id"));
                                     fra.add(jo.getString("fra"));
                                     deu.add(jo.getString("deu"));


                                 }

                                 listView.setAdapter(listViewAdapter);


                             } else {
                                 Toast.makeText(getActivity(), "No Details Found", Toast.LENGTH_SHORT).show();
                             }
                         } catch (JSONException e) {
                             Log.d("exception", e.toString());
                         }
                     }

                     @Override
                     public void failure(RetrofitError error) {
                         Log.d("Failure", error.toString());
                         Toast.makeText(getActivity(), error.toString(), Toast.LENGTH_LONG).show();
                     }
                 }
    );
  }

}

This is the listViewAdpater class :这是 listViewAdpater 类:

public class ListViewAdapter extends BaseAdapter {

private final Context context;
private ArrayList<String> id = new ArrayList<String>();
private ArrayList<String> fra = new ArrayList<String>();
private ArrayList<String> deu = new ArrayList<String>();
LayoutInflater layoutInflater;

public ListViewAdapter(Context ctx, ArrayList<String> id, ArrayList<String> fra, ArrayList<String> deu) {

    this.context = ctx;
    this.id = id;
    this.fra = fra;
    this.deu = deu;

}

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

@Override
public Object getItem(int position) {
    return id.get(position);
}

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

@SuppressLint("ViewHolder")
@Override
public View getView(final int position, View view, ViewGroup parent) {

    final Holder holder;
    if (view == null) {
        layoutInflater = (LayoutInflater) context.getSystemService
                (Context.LAYOUT_INFLATER_SERVICE);

        view = layoutInflater.inflate(R.layout.list_item, null);
        holder = new Holder();
        holder.txt_fra = (TextView) view.findViewById(R.id.fra);
        holder.txt_deu = (TextView) view.findViewById(R.id.deu);
        view.setTag(holder);
    } else {

        holder = (Holder) view.getTag();
    }

        holder.txt_fra.setText(fra.get(position));
        holder.txt_deu.setText(deu.get(position));


        return view;
    }

    static class Holder {
        TextView txt_fra, txt_deu;
    }

}

Should I create a method to refresh my ListView ?我应该创建一个方法来刷新我的ListView吗?

First of all I would suggest to remove the unnecessary initialization of your variables inside the Adapter:首先,我建议删除适配器内不必要的变量初始化:

private ArrayList<String> id = new ArrayList<String>();
private ArrayList<String> fra = new ArrayList<String>();
private ArrayList<String> deu = new ArrayList<String>();

By assigning the pointer from your fragment you will already assign an initialized ArrayList.通过从您的片段分配指针,您将已经分配了一个初始化的 ArrayList。 You want both pointers to point at the same ArrayList Object so changes apply to both.您希望两个指针都指向同一个 ArrayList 对象,以便更改适用于两者。

Apparently, the data stored in the Adapter is not being updated correctly.显然,存储在适配器中的数据没有正确更新。 I would suggest to debug your app - setting the breakpoint so that you can see the data that the Adapter stores after an update.我建议调试您的应用程序 - 设置断点,以便您可以看到更新后适配器存储的数据。

The idea of writing a method for updates has already been implemented with the notifyDataSetChanged() .编写更新方法的想法已经通过notifyDataSetChanged()实现了。 Just override the method in your adapter and do eventual changes before calling the super.notifyDataSetChanged() .只需覆盖适配器中的方法并在调用super.notifyDataSetChanged()之前进行最终更改。

If you have any success with those changes let us know.如果您在这些更改方面取得任何成功,请告诉我们。

buttonadd.setOnClickListener(new View.OnClickListener() {
        ...
        insert_data();
       listViewAdapter.notifyDataSetChanged();

    }
});

In your onClickListener , you are calling insert_data() , followed by listViewAdapter.notifyDataSetChanged()在您的onClickListener ,您正在调用insert_data() ,然后是listViewAdapter.notifyDataSetChanged()

insert_data() method is sending a network request to retrieve the data to populate the list. insert_data()方法正在发送网络请求以检索数据以填充列表。 BUT, you are calling notifyDataSetChanged BEFORE the network request is done.但是,您在网络请求完成之前调用notifyDataSetChanged That's why the listView is empty, and will stay empty.这就是为什么listView是空的,并且将保持为空。 You need to wait AFTER the network request and AFTER you have populated your ArrayList with the data to call notifyDataSetChanged .您需要在网络请求之后等待,并且在您使用数据填充ArrayList以调用notifyDataSetChanged How do we know the network request is done?我们如何知道网络请求已完成? Simply at the end of the callback (which you've implemented):只需在回调结束时(您已实现):

new Callback<Response>() {
            @Override
            public void success(Response result, Response response) {...

At the end of the success method, you call listViewAdapter.notifyDataSetChanged() method.success方法的最后,您调用listViewAdapter.notifyDataSetChanged()方法。

Hope that makes sense!希望这是有道理的! Try it and let us know what happens尝试一下,让我们知道会发生什么

I've founded a solution.我已经建立了一个解决方案。 I've added getActivity.recreate();我添加了getActivity.recreate(); in the method insert_data .在方法insert_data 中

public void success(Response result, Response response) {

                    try {

                        BufferedReader reader = new BufferedReader
                                (new InputStreamReader(result.getBody().in()));
                        String resp;
                        resp = reader.readLine();
                        Log.d("success", "" + resp);

                        JSONObject jObj = new JSONObject(resp);
                        int success = jObj.getInt("success");

                        if(success == 1){
                            Toast.makeText(getActivity(), "Successfully inserted",
                                    Toast.LENGTH_SHORT).show();
                            getActivity().recreate();

                        } else{
                            Toast.makeText(getActivity(), "Insertion Failed",
                                    Toast.LENGTH_SHORT).show();
                        }

                    } catch (IOException e) {
                        Log.d("Exception", e.toString());
                    } catch (JSONException e) {
                        Log.d("JsonException", e.toString());
                    }


                }

I'm not sure that is the best solution but it works.我不确定这是最好的解决方案,但它有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM