【问题标题】:Load more list with JSON array Android使用 JSON 数组 Android 加载更多列表
【发布时间】:2017-08-31 05:35:44
【问题描述】:

我必须了解 JSON 数组解析并加载到 ListView 中,其功能类似于在滚动事件中加载更多数据。

下面是我的课程代码。

public class MainActivity extends AppCompatActivity {

String URL = "API-URL";
int page_number = 1;
ListView lv;
ArrayList<ArrayList<HashMap<String,String>>> data = new ArrayList<ArrayList<HashMap<String,String>>>();
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    lv = findViewById(R.id.listview);
    new PerformTask().execute();
}
ProgressDialog mProgressDialog;
private class PerformTask extends AsyncTask<Void, Void, String> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();

        mProgressDialog = new ProgressDialog(MainActivity.this);
        mProgressDialog.setMessage("Loading...");
        mProgressDialog.setIndeterminate(false);
        mProgressDialog.show();
    }

    @Override
    protected String doInBackground(Void... params) {

        String json="";
        try {

            JSONParser jsonParser = new JSONParser();
            json = jsonParser.getJSONdata(URL,page_number++);
            Log.e("jsonResponse", json + "");

        } catch (Exception e) {
            e.printStackTrace();
        }

        return json;

    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);

        if (!result.equals("")) {
            try {
                JSONObject jsonObj = new JSONObject(result);
                JSONArray dataArray = jsonObj.optJSONArray("key");
                for(int i = 0; i<dataArray.length(); i++){
                    ArrayList<HashMap<String,String>> dataArrayList = new ArrayList<HashMap<String,String>>();
                    JSONArray dataArray_inner = dataArray.getJSONArray(i);
                    for(int j = 0; j<dataArray_inner.length(); j++){
                        JSONObject object22 = dataArray_inner.optJSONObject(j);
                        HashMap<String, String> hashMap = new HashMap<>();
                        hashMap.put("your_key", object22.getString("key_data"));
                        hashMap.put("your_key", object22.getString("post_content"));
                        dataArrayList.add(hashMap);
                    }
                    data.add(dataArrayList);
                }
                if(data.size() > 0){
                    Log.e("Data ","Data are available");

                    AdapterMain adapter = new AdapterMain(MainActivity.this, data);
                    lv.setAdapter(adapter);

                    lv.setOnScrollListener(new AbsListView.OnScrollListener() {
                        @Override
                        public void onScrollStateChanged(AbsListView absListView, int i) {
                            int threshold = 1;
                            int count = lv.getAdapter().getCount();
                            if (i == SCROLL_STATE_IDLE) {
                                if (lv.getLastVisiblePosition() >= count
                                        - threshold) {
                                    // Execute LoadMorePerformTask AsyncTask;
                                    new LoadMorePerformTask().execute();
                                }
                            }
                        }

                        @Override
                        public void onScroll(AbsListView absListView, int i, int i1, int i2) {

                        }
                    });
                }

            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        mProgressDialog.dismiss();
    }
}

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

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        mProgressDialog = new ProgressDialog(MainActivity.this);
        mProgressDialog.setMessage("Loading more...");
        mProgressDialog.setIndeterminate(false);
        mProgressDialog.show();
    }

    @Override
    protected String doInBackground(Void... params) {

        String json="";
        try {

            JSONParser jsonParser = new JSONParser();
            json = jsonParser.getJSONdata(URL,page_number++);
            Log.e("jsonResponse", json + "");

        } catch (Exception e) {
            e.printStackTrace();
        }
        return json;
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);

        if (!result.equals("")) {
            try {
                JSONObject jsonObj = new JSONObject(result);
                JSONArray dataArray = jsonObj.optJSONArray("key");
                for(int i = 0; i<dataArray.length(); i++){
                    ArrayList<HashMap<String,String>> dataArrayList = new ArrayList<HashMap<String,String>>();
                    JSONArray dataArray_inner = dataArray.getJSONArray(i);
                    for(int j = 0; j<dataArray_inner.length(); j++){
                        JSONObject object22 = dataArray_inner.optJSONObject(j);
                        HashMap<String, String> hashMap = new HashMap<>();
                        hashMap.put("your_key", object22.getString("key_data"));
                        hashMap.put("your_key", object22.getString("key_data"));
                        dataArrayList.add(hashMap);
                    }
                    data.add(dataArrayList);
                }
                if(data.size() > 0){
                    Log.e("Data ","Data are available");
                    int lv_position = lv.getLastVisiblePosition();
                    AdapterMain adapter = new AdapterMain(MainActivity.this, data);
                    lv.setAdapter(adapter);

                    lv.setSelectionFromTop(lv_position, 0);

                }

            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        mProgressDialog.dismiss();
    }
}
}

适配器类代码可在此处获得。

public class AdapterMain extends BaseAdapter {

// Declare Variables
Context mContext;
LayoutInflater inflater;
private ArrayList<ArrayList<HashMap<String,String>>> arraylist;
protected int count;

public AdapterMain(Context context, ArrayList<ArrayList<HashMap<String,String>>> numberlist) {
    mContext = context;
    inflater = LayoutInflater.from(mContext);
    this.arraylist = new ArrayList<ArrayList<HashMap<String,String>>>();
    this.arraylist.addAll(numberlist);
}

public class ViewHolder {
    TextView title1, description1, title2, description2;
    RelativeLayout rel_second;
}

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

@Override
public ArrayList<HashMap<String,String>> getItem(int position) {
    return arraylist.get(position);
}

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

public View getView(final int position, View view, ViewGroup parent) {
    final ViewHolder holder;
    if (view == null) {
        holder = new ViewHolder();

        view = inflater.inflate(R.layout.row_view, null);
        holder.rel_second = (RelativeLayout) view.findViewById(R.id.rel_second);
        holder.title1 = (TextView) view.findViewById(R.id.title1);
        holder.description1 = (TextView) view.findViewById(R.id.description1);
        holder.title2 = (TextView) view.findViewById(R.id.title2);
        holder.description2 = (TextView) view.findViewById(R.id.description2);

        view.setTag(holder);
    } else {
        holder = (ViewHolder) view.getTag();
    }

    // Set the results into TextView
    holder.title1.setText(arraylist.get(position).get(0).get("key1"));
    holder.description1.setText(arraylist.get(position).get(0).get("key2"));

        holder.rel_second.setVisibility(View.VISIBLE);
        holder.title2.setText(arraylist.get(position).get(1).get("key1"));
        holder.description2.setText(arraylist.get(position).get(1).get("key2"));

    // Listen for ListView Item Click
    view.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View arg0) {
          // Click Perform of Item
        }
    });

    return view;
}
}

JSONParser 类在这里。

public class JSONParser {

static InputStream is = null;
public JSONParser() {
}

public String getJSONdata(String URL, int pageNumber){
    String response_str = "";
    try {
        HttpClient client = new DefaultHttpClient();
        HttpPost post = new HttpPost(URL);
        post.addHeader(new BasicHeader("parameter_key", ""+pageNumber));
        HttpResponse response = client.execute(post);
        HttpEntity entity = response.getEntity();
        is = entity.getContent();

        BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
        StringBuilder sb = new StringBuilder();
        String line = null;
        while ((line = reader.readLine()) != null) {
            sb.append(line + "\n");
        }
        is.close();
        response_str=sb.toString();
    } catch (Exception e){
        e.printStackTrace();
    }
    return response_str;
}

} 

这是 Gradle 文件代码。

android {
compileSdkVersion 26
buildToolsVersion "26.0.1"
useLibrary  'org.apache.http.legacy'
defaultConfig {
    applicationId "testdemoapp.sandy.com.myapplication"
    minSdkVersion 19
    targetSdkVersion 26
    versionCode 1
    versionName "1.0"
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}
packagingOptions {
    exclude 'META-INF/LICENSE'
}
}

dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
androidTestImplementation('com.android.support.test.espresso:espresso-core:3.0.0', {
    exclude group: 'com.android.support', module: 'support-annotations'
})
implementation 'com.android.support:appcompat-v7:26.0.1'
testImplementation 'junit:junit:4.12'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'

compile 'org.apache.httpcomponents:httpcore:4.4.1'

}

在这个问题上,我在滚动加载更多数据时遇到了问题。有时它会调用两次 AsyncTask 并加载比所需更多的数据。

如果有人有任何想法,请告诉我。 提前致谢。

【问题讨论】:

  • 是的,因为异步需要时间来更新您的数据,同时它仍然滚动并再次执行您的操作,放置日志以了解确切的问题
  • 我将 progressDialog 放在 AsyncTask 执行上,因此,当它执行时,用户将等待获取数据并完成进度任务。但是,我有时遇到的问题是 AsyncTask 调用,我正在等待完成进程,而不是在完成该进程后自动启动新进程。
  • 当 recyclerview 获取最后一项时,您的 asynctask 将调用它,但它会创建新线程,因此您的主线程会获得滚动事件,因此它再次调用 asynctask 并且 asynctask 将被一个一个执行
  • 你必须使用条件来管理这种行为
  • 我使用带有滚动项目位置和列表视图中可用项目总数的条件来管理它。

标签: android json listview


【解决方案1】:

您应该为此使用布尔值。

lv.setOnScrollListener(new AbsListView.OnScrollListener() {
                        @Override
                        public void onScrollStateChanged(AbsListView absListView, int i) {
                            int threshold = 1;
                            int count = lv.getAdapter().getCount();
                            if (i == SCROLL_STATE_IDLE) {
                                if (lv.getLastVisiblePosition() >= count
                                        - threshold) {
                                    // Execute LoadMorePerformTask AsyncTask;
                                    new LoadMorePerformTask().execute();
                                }
                            }
                        }

                        @Override
                        public void onScroll(AbsListView absListView, int i, int i1, int i2) {

                        }
                    });

问题出在您的代码中。您正在创建每个列表到达其底部的请求。您需要保留一个布尔值isLoaded = false,并且在列表到达底部时触发请求之前检查isLoaded 是否为true,然后触发请求并在您的异步任务中,您可以在收到并设置结果时将布尔值设置为true触发请求后它为 false。

if (i == SCROLL_STATE_IDLE) {
         if (lv.getLastVisiblePosition() >= count- threshold) {
            // Execute LoadMorePerformTask AsyncTask;                                  
              if(isLoaded){
               new LoadMorePerformTask().execute();
              isLoaded=false
       }
       }

在 aysc 中

protected void onPostExecute(String result) {
        super.onPostExecute(result);
         isLoaded = true; //and your rest of the code}

希望这会有所帮助。

【讨论】:

  • -->Mr.Sandy 正是我向您传达的内容和@Zeeshan 不错的答案
  • 我添加了我的答案以获得更多理解。 @PriteshVadhiya您可以对不错的答案投票:P
  • 只要确保 isLoaded = true;仅当执行的请求对其响应具有有效数据时,否则您将收到相同的错误。
猜你喜欢
  • 2012-10-08
  • 2015-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-13
  • 2021-09-08
  • 1970-01-01
  • 2017-05-05
相关资源
最近更新 更多