android - 使用 JSON 数组 Android 加载更多列表

标签 android json listview

我必须了解在 ListView 中解析和加载 JSON 数组的功能,例如在滚动事件上加载更多数据。

下面是我的类(class)代码。

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 两次并加载比需要更多的数据。

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

最佳答案

你应该为此使用 bool 值。

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) {

                        }
                    });

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

希望这会有所帮助。

关于android - 使用 JSON 数组 Android 加载更多列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45973921/

相关文章:

ajax - 避免 Django 的 QueryDict 列表限制

c# - JSON.NET 反序列化客户端

java - ListView中每行的颜色不同,我也想拖动该行,并且每行的背景颜色也要交换。怎么做

c# - 在 c# listview 中有一列在开头而不是结尾处被截断

android - 无法加载新的空白 Activity - Android 教程

android - 在 Kotlin 中解析二维数组

ios - 以 Json 格式发布请求 iOS

c# - ListView 中选中项的颜色

android - 是否可以在 iOS 应用程序和 Android 应用程序之间轻松共享数据?

android - 在 Android 中执行服务的最佳方法