Reputation: 4349
I have to know about the JSON array parse and load in ListView with functioning like load more data on scrolling event.
Below is my class code.
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();
}
}
}
Adapter class code available here.
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 class is here.
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;
}
}
And this is Gradle file code.
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'
}
In this I get problem with load more data on scroll. sometimes it called AsyncTask twice and load more data than required.
If anyone have any idea than please let me know. Thanks in advance.
Upvotes: 3
Views: 450
Reputation: 7114
You should use boolean for that.
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) {
}
});
The problem is here in your code. You are create request every list reaches to its bottom. You need to keep a boolean isLoaded = false
and before firing the request when list reaches to its bottom check if isLoaded
is true
then fire the request and in your async task you can set the boolean true when result is received and set it to false after firing the request.
if (i == SCROLL_STATE_IDLE) {
if (lv.getLastVisiblePosition() >= count- threshold) {
// Execute LoadMorePerformTask AsyncTask;
if(isLoaded){
new LoadMorePerformTask().execute();
isLoaded=false
}
}
and in aysc
protected void onPostExecute(String result) {
super.onPostExecute(result);
isLoaded = true; //and your rest of the code}
Hope this will help.
Upvotes: 2