滑动即可刷新

时间:2018-08-26 08:18:21

标签: java android pull-to-refresh android-swipe

我是Java和Android开发的新手。

坚持在Android中实现“刷新以刷新” 。我正在尝试访问其他类中的方法。我将突出显示android studio在blockquote中给出的错误。非常感谢您的帮助。

MainActivity.java

import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;

public class MainActivity extends AppCompatActivity{

private String TAG = MainActivity.class.getSimpleName();

private SwipeRefreshLayout swipeRefreshLayout;
private ProgressDialog pDialog;
private ListView lv;

// URL to get contacts JSON
private static String url = "http://hooman.com/hoo.php";

ArrayList<HashMap<String, String>> contactList;

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

    contactList = new ArrayList<>();
    swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swiperefresh);


    lv = (ListView) findViewById(R.id.list);
    swipeRefreshLayout.setOnRefreshListener(this);
    swipeRefreshLayout.post(new Runnable() {
                                @Override
                                public void run() {
                                    swipeRefreshLayout.setRefreshing(true);
                                    doInBackground();
                                }
                            }
    );
    new GetContacts().execute();
}
@Override
public void onRefresh() {
    doInBackground();
}
/**
 * Async task class to get json by making HTTP call
 */
private class GetContacts extends AsyncTask<Void, Void, Void> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        // Showing progress dialog
        pDialog = new ProgressDialog(MainActivity.this);
        pDialog.setMessage("Please wait...");
        pDialog.setCancelable(false);
        pDialog.show();

    }

    @Override
    protected Void doInBackground(Void... arg0) {
        HttpHandler sh = new HttpHandler();
        swipeRefreshLayout.setRefreshing(true);
        // Making a request to url and getting response
        String jsonStr = sh.makeServiceCall(url);

        Log.e(TAG, "Response from url: " + jsonStr);

        if (jsonStr != null) {
            try {

                JSONArray contacts = new JSONArray(jsonStr);

                // looping through All Contacts
                for (int i = 0; i < contacts.length(); i++) {
                    JSONObject c = contacts.getJSONObject(0);

                    String kw = c.getString("kw");
                    String kva = c.getString("kva");
                    String pf = c.getString("pf");

                    // tmp hash map for single contact
                    HashMap<String, String> contact = new HashMap<>();

                    // adding each child node to HashMap key => value
                    contact.put("kw", kw);
                    contact.put("kva", kva);
                    contact.put("pf", pf);

                    // adding contact to contact list
                    contactList.add(contact);

                    // stopping swipe refresh
                    swipeRefreshLayout.setRefreshing(false);
                }
            } catch (final JSONException e) {
                Log.e(TAG, "Json parsing error: " + e.getMessage());
                Log.e("JSON Parser", "Error parsing data " + e.toString());
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(getApplicationContext(),
                                "Json parsing error: " + e.getMessage(),
                                  Toast.LENGTH_LONG)
                                .show();
                    }
                });

            }
        } else {
            Log.e(TAG, "Couldn't get json from server.");
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(getApplicationContext(),
                            "Couldn't get json from server. Check LogCat for possible errors!",
                            Toast.LENGTH_LONG)
                            .show();
                    // stopping swipe refresh
                    swipeRefreshLayout.setRefreshing(false);
                }
            });

        }

        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        super.onPostExecute(result);
        // Dismiss the progress dialog
        if (pDialog.isShowing())
            pDialog.dismiss();
        /**
         * Updating parsed JSON data into ListView
         * */
        ListAdapter adapter = new SimpleAdapter(
                MainActivity.this, contactList,
                R.layout.list_item, new String[]{"kw", "kva",
                "pf"}, new int[]{R.id.kw,
                R.id.kva, R.id.pf});

        lv.setAdapter(adapter);
    }

}
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/swiperefresh"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<ListView
    android:id="@+id/list"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" />
</android.support.v4.widget.SwipeRefreshLayout>

list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="10dp">

    <TextView
        android:id="@+id/kw"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingBottom="2dip"
        android:paddingTop="6dip"
        android:textColor="@color/colorPrimaryDark"
        android:textSize="16sp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/kva"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingBottom="2dip"
        android:textColor="@color/colorAccent" />

    <TextView
        android:id="@+id/pf"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#5d5d5d"
        android:textStyle="bold" />
</LinearLayout>

谢谢。

2 个答案:

答案 0 :(得分:1)

首先,您具有循环依赖关系。 AsyncTask无法引用“活动”中的swipeRefreshLayout视图,并且活动将需要一个任务实例才能调用task.doInBackground()(您应该绝对不要这样做”)。只需要使用execute(),很少使用execute().get()

您可以做的是在活动中覆盖postExecute函数

swipeRefreshLayout.post(new Runnable() {
        @Override
        public void run() {
            swipeRefreshLayout.setRefreshing(true);

            // Showing progress dialog
            final ProgressDialog pDialog = new ProgressDialog(MainActivity.this);
            pDialog.setMessage("Please wait...");
            pDialog.setCancelable(false);
            pDialog.show();

            contactList.clear();

            new GetContacts() {

              @Override
              protected void onPostExecute(Void result) {
                  // stopping swipe refresh
                  swipeRefreshLayout.setRefreshing(false);

                  // Dismiss the progress dialog
                  if (pDialog.isShowing())
                      pDialog.dismiss();

                  ListAdapter adapter = new SimpleAdapter(
                  MainActivity.this, contactList, R.layout.list_item, 
                  new String[]{"kw", "kva", "pf"}, 
                  new int[]{R.id.kw,R.id.kva, R.id.pf});

                  lv.setAdapter(adapter);  

                }
            }.execute();
        }
    }
);

答案 1 :(得分:0)

首先,不要从doInBackground()方法调用UI视图。

您可以通过onPreExcute()方法或onPostExecute方法调用它们。

但是由于AsyncTask在其他文件中,因此您也不能直接调用它们。


由于您要在刷新SwipeRefreshLayout时执行AsyncTask代码。

有2种方法:

1st:使AsyncTask类成为调用活动的内部类。 (仅在您仅要在此活动中使用此Asynctask时有用。

2nd:在AsyncTask How to get the result of OnPostExecute() to main activity because AsyncTask is a separate class?

中实现回调

3:使用排球/翻新(库)。 (由于您仅调用API并获取JSON数据,因此默认情况下,它们使用“主线程以外的其他线程”,并且也内置了JSON支持。