【问题标题】:Swipe to refresh滑动刷新
【发布时间】:2018-08-26 08:18:20
【问题描述】:

我是 Java 和 Android 开发的新手。

坚持在 android 中实现 "SWIPE TO REFRESH"。我正在尝试访问其他类中的方法。我将强调 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>

提前致谢。

【问题讨论】:

  • 你真正想要什么?是否要调用 GetContacts AsyncTask 类的 doInBackground() 函数?
  • 你为什么要发private class

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


【解决方案1】:

首先,你有循环依赖。 AsyncTask 不能在 Activity 中引用 swipeRefreshLayout 视图,并且 Activity 需要一个任务实例才能调用 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();
        }
    }
);

【讨论】:

    【解决方案2】:

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

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

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


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

    有两种方式:

    第一个:使 AsyncTask 类成为调用活动的内部类。 (仅当您打算仅在此活动中使用此 Asynctask 时才有用。

    第二个:在 AsyncTask 中实现回调 How to get the result of OnPostExecute() to main activity because AsyncTask is a separate class?

    3:使用 Volley / Retrofit(库)。 (由于您只是调用 API 并获取 JSON 数据,因此它们默认使用“除主线程之外的其他线程”,并且还内置了 JSON 支持。

    【讨论】:

      猜你喜欢
      • 2017-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-18
      • 2021-04-19
      相关资源
      最近更新 更多