I would like to populate my Listview using a loop, I have recently attempted to populate it in a very inefficient way by making multiple calls for the data from SQL. When I realized just how inefficient it was I began to pull the data from the server in one go by making use of arrays. I am having trouble changing my code for this to work.
What I need to do is find a way of looping through the below array of JSONArrays (Which is not the hard part for me), but to do so I need to have my GetSocietyDataASyncTask return the above array and find a way of passing it to the OnCreate/done method in SocietySearch.java (Alot of the Society objects in my code can be ignored and somehow replaced with List societies)
Now I believe that I have included all of the relevant code but if you need to see anything else please do not hesitate to ask me.
The data that is received by Java from my database looks like this:
[{"society_id":1,"name":"TestName1","email":"Test#email1","description":"TestDes1"},
{"society_id":2,"name":"TestName2","email":"Test#email2","description":"TestDes2"}]
SocietySearch Class:
public class SocietySearch extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_society_search);
Society society = new Society(-1, null, null, null);
ServerRequests serverRequest1 = new ServerRequests(SocietySearch.this);
serverRequest1.GetSocietyDataAsyncTask(society, new GetSocietyCallback() {
#Override
public void done(final Society returnedSociety) {
ListView lv = (ListView) findViewById(R.id.ListView);
List<ListViewItem> items = new ArrayList<>();
items.add(new ListViewItem() {{
ThumbnailResource = R.drawable.test;
Title = returnedSociety.socName;
Subtitle = returnedSociety.socDes;
}});
CustomListViewAdapter adapter = new CustomListViewAdapter(SocietySearch.this, items);
lv.setAdapter(adapter);
}
});
}
class ListViewItem {
public int ThumbnailResource;
public String Title;
public String Subtitle;
}
Relevant Part Of ServerRequests Class:
public class getSocietyDataAsyncTask extends AsyncTask<Void, Void, Society> {
Society society;
GetSocietyCallback societyCallback;
public getSocietyDataAsyncTask(Society society, GetSocietyCallback societyCallback) {
this.society = society;
this.societyCallback = societyCallback;
}
#Override
protected Society doInBackground(Void... params) {
BufferedReader reader = null;
Society returnedSociety = null;
List<Society> societies = new ArrayList<>();
try {
URL url = new URL(SERVER_ADDRESS + "/getsocietydata.php");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setConnectTimeout(CONNECTION_TIMEOUT);
con.setReadTimeout(CONNECTION_TIMEOUT);
con.setRequestMethod("POST");
con.setDoOutput(true);
StringBuilder sb = new StringBuilder();
reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
String line;
while ((line = reader.readLine()) != null) { //Read until there is something available
sb.append(line + "\n"); //Read and save line by line
}
line = sb.toString(); //Saving complete data received in string
//Check values received in Logcat
Log.i("custom_check", "The values received in the store part are as follows:");
Log.i("custom_check", line);
JSONArray ja = new JSONArray(line);
if (ja != null && ja.length() == 0) {
returnedSociety = null;
} else {
for (int i = 0; i <ja.length(); i++) {
JSONObject json = ja.optJSONObject(i);
//Storing each Json in a variable
int society_id = json.getInt("society_id");
String socName = json.getString("name");
String socEmail = json.getString("email");
String socDes = json.getString("description");
returnedSociety = new Society(society_id, socName, socEmail, socDes);
societies.add(returnedSociety);
}
return returnedSociety;
}
} catch (Exception e) {
e.printStackTrace();
Log.d("Sample", "Error has occurred!\n" + e.toString());
}
finally {
if (reader != null) {
try {
reader.close(); //Closing the
} catch (IOException e) {
e.printStackTrace();
}
}
}
return returnedSociety;
}
#Override
protected void onPostExecute(Society returnedSociety) {
super.onPostExecute(returnedSociety);
progressDialog.dismiss();
societyCallback.done(returnedSociety);
}
}
CustomListViewAdapter.java:
public class CustomListViewAdapter extends BaseAdapter {
LayoutInflater inflater;
List<SocietySearch.ListViewItem> items;
public CustomListViewAdapter(Activity context, List<SocietySearch.ListViewItem> items) {
super();
this.items = items;
this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
//Auto-generated method stub
return items.size(); // TODO Maybe this can be my sql count?
}
#Override
public Object getItem(int position) {
//Auto-generated method stub
return null;
}
#Override
public long getItemId(int position) {
//Auto-generated method stub
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
//Auto-generated method stub
ListViewItem item = items.get(position);
View vi = convertView;
if (convertView == null)
vi = inflater.inflate(R.layout.item_row, null);
ImageView test = (ImageView) vi.findViewById(R.id.imgThumbnail);
TextView txtTitle = (TextView) vi.findViewById(R.id.txtTitle);
TextView txtSubTitle = (TextView) vi.findViewById(R.id.txtSubTitle);
test.setImageResource(item.ThumbnailResource);
txtTitle.setText(item.Title);
txtSubTitle.setText(item.Subtitle);
return vi;
}
}
ListView Layour file (item_row.xml):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/relativeLayout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dip">
<ImageView
android:id="#+id/imgThumbnail"
android:layout_width="78dip"
android:layout_height="78dip"
android:layout_alignParentLeft="true"
android:layout_centerInParent="true"
android:layout_marginLeft="-3dip"
android:scaleType="centerInside"></ImageView>
<TextView
android:id="#+id/txtTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="6dip"
android:layout_marginTop="6dip"
android:layout_toRightOf="#+id/imgThumbnail"
android:text="TextView"
android:textAppearance="?android:attr/textAppearanceLarge"></TextView>
<TextView
android:id="#+id/txtSubTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/txtTitle"
android:layout_marginLeft="6dip"
android:layout_marginTop="3dip"
android:layout_toRightOf="#+id/imgThumbnail"
android:text="TextView"></TextView>
</RelativeLayout>
Take a look at ArrayAdapter and specifically #notifyDataSetChanged. (notifyDataSetChanged example). You can setup the ListView in #onCreate like you have and store off a reference to the underlying Adapter. Initially the Adapter will be empty, but when data comes in simply add it to the Adapter and call #notifyDataSetChanged as guided in the example.
Related
Here I am trying to display the name and price of the test.
and I'm taking a recycler view to do the same using the JET Parsing GET method.
But I'm not getting anything in my business and showing myself black there.
here is my code
please help me find the solution.
Model class
public class TestListsModel {
public String test_price;
public String testlist_id;
public String test_name;
}
This is my Adapter:
public class AdapterTestList extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private LayoutInflater inflater;
List<TestListsModel> data= Collections.emptyList();
TestListsModel current;
int currentPos=0;
// create constructor to innitilize context and data sent from MainActivity
public AdapterTestList(Context context, List<TestListsModel> data){
this.context=context;
inflater= LayoutInflater.from(context);
this.data=data;
}
// Inflate the layout when viewholder created
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view=inflater.inflate(R.layout.test_list_row, parent,false);
MyHolder holder=new MyHolder(view);
return holder;
}
// Bind data
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
// Get current position of item in recyclerview to bind data and assign values from list
MyHolder myHolder= (MyHolder) holder;
TestListsModel current=data.get(position);
myHolder.testName.setText(current.test_name);
myHolder.testPrice.setText( current.test_price);
// load image into imageview using glide
/* Glide.with(context).load("http://192.168.1.7/test/images/" + current.fishImage)
.placeholder(R.drawable.ic_img_error)
.error(R.drawable.ic_img_error)
.into(myHolder.ivFish);*/
}
// return total item from List
#Override
public int getItemCount() {
return data.size();
}
class MyHolder extends RecyclerView.ViewHolder{
TextView testName;
TextView testPrice;
// create constructor to get widget reference
public MyHolder(View itemView) {
super(itemView);
testName = (TextView) itemView.findViewById(R.id.test_name);
testPrice = (TextView) itemView.findViewById(R.id.price_name);
}
}
}
This is my Activity Class:
public class HealthServicesActivity extends AppCompatActivity implements View.OnClickListener {
SharePreferenceManager<LoginModel> sharePreferenceManager;
// CONNECTION_TIMEOUT and READ_TIMEOUT are in milliseconds
public static final int CONNECTION_TIMEOUT = 10000;
public static final int READ_TIMEOUT = 15000;
private RecyclerView testListRecylerView;
private AdapterTestList mAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_health_services);
ButterKnife.bind(this);
sharePreferenceManager = new SharePreferenceManager<>(getApplicationContext());
dayTimeDisplay();
new AsyncLogin().execute();
}
private class AsyncLogin extends AsyncTask<String, String, String> {
//ProgressDialog pdLoading = new ProgressDialog(getApplicationContext());
HttpURLConnection conn;
URL url = null;
#Override
protected void onPreExecute() {
super.onPreExecute();
//this method will be running on UI thread
/* pdLoading.setMessage("\tLoading...");
pdLoading.setCancelable(false);
pdLoading.show();*/
}
#Override
protected String doInBackground(String... params) {
try {
String url_test="http://192.168.1.80/aoplnew/api/users/gettestlist/"+sharePreferenceManager.getUserLoginData(LoginModel.class).getResult().getCenterId();
// Enter URL address where your json file resides
// Even you can make call to php file which returns json data
//url = new URL("http://192.168.1.7/test/example.json");
url = new URL(url_test);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return e.toString();
}
try {
// Setup HttpURLConnection class to send and receive data from php and mysql
conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(READ_TIMEOUT);
conn.setConnectTimeout(CONNECTION_TIMEOUT);
conn.setRequestMethod("GET");
// setDoOutput to true as we recieve data from json file
conn.setDoOutput(true);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
return e1.toString();
}
try {
int response_code = conn.getResponseCode();
// Check if successful connection made
if (response_code == HttpURLConnection.HTTP_OK) {
// Read data sent from server
InputStream input = conn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
StringBuilder result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
// Pass data to onPostExecute method
return (result.toString());
} else {
return ("[]");
}
} catch (IOException e) {
e.printStackTrace();
return e.toString();
} finally {
conn.disconnect();
}
}
#Override
protected void onPostExecute(String result) {
//this method will be running on UI thread
//pdLoading.dismiss();
List<TestListsModel> data=new ArrayList<>();
//pdLoading.dismiss();
try {
JSONArray jArray = new JSONArray(result);
// Extract data from json and store into ArrayList as class objects
for(int i=0;i<jArray.length();i++){
JSONObject json_data = jArray.getJSONObject(i);
TestListsModel testData = new TestListsModel();
testData.testlist_id= json_data.getString("testlist_id");
testData.test_name= json_data.getString("test_name");
testData.test_price= json_data.getString("test_price");
data.add(testData);
}
// Setup and Handover data to recyclerview
testListRecylerView = (RecyclerView)findViewById(R.id.test_list_recycler_view);
mAdapter = new AdapterTestList(HealthServicesActivity.this, data);
testListRecylerView.setAdapter(mAdapter);
testListRecylerView.setLayoutManager(new LinearLayoutManager(HealthServicesActivity.this));
} catch (JSONException e) {
Toast.makeText(HealthServicesActivity.this, e.toString(), Toast.LENGTH_LONG).show();
}
}
}
}
Thanks in advance for any answer!
You need to set the setLayoutManager before the setting the adapter like below. In your code, you have setAdapter() before the setLayoutManager therefore your adapter not set properly.
Refer this for the further explanation https://developer.android.com/guide/topics/ui/layout/recyclerview
testListRecylerView = (RecyclerView)findViewById(R.id.test_list_recycler_view);
mAdapter = new AdapterTestList(HealthServicesActivity.this, data);
/**
* SET THE LAYOUT MANAGER BEFORE SETTING THE ADAPTER
*/
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(HealthServicesActivity.this);
testListRecylerView.setLayoutManager(mLayoutManager);
testListRecylerView.setItemAnimator(new DefaultItemAnimator());
/**
* AND THAN SET THE ADAPTER
*/
testListRecylerView.setAdapter(mAdapter);
I am trying to show data in custom listView using API
there is no error but data is not shown in custom list .i made separate
class for asyncTask ,Adapters and model.
code of asyncTask is
public class CourseOutlinesTask extends AsyncTask<String, String, String> {
ProgressDialog dialog;
Context context;
private ArrayList<CourseModel> postList = new ArrayList<CourseModel>();
private ListView listView;
private View root;
TrainerCourseAdapter adapter;
String json_string;
#Override
protected void onPreExecute() {
}
#Override
protected String doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
return buffer.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection != null)
connection.disconnect();
try {
if (reader != null)
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
//close process dialog
if (this.dialog != null) {
this.dialog.dismiss();
}
//parse json
try {
JSONObject jsonParse = new JSONObject(result);
JSONArray query = jsonParse.getJSONArray("courses");
for (int i = 0; i < query.length(); i++) {
try {
JSONObject jsonParser = query.getJSONObject(i);
CourseModel post = new CourseModel();
post.setId(jsonParser.getInt("id"));
post.setTitle(jsonParser.getString("title"));
post.setStatus(jsonParser.getString("status"));
post.setDescription(jsonParser.getString("description"));
System.out.println(post.getStatus()+"asdadasdad");
System.out.println(post);
postList.add(post);
TrainerCourseAdapter adapter = new TrainerCourseAdapter(context,postList);
}catch (Exception e) {
System.out.println(e);
}
// Parsing json
post.setDescription(obj.getString("description"));
// ****Handle CreationDate-Object
// Genre is json array
}
} else {
MyAppUtil.getToast(getApplicationContext(), message);
}*/
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
code of my adapter class is
public class TrainerCourseAdapter extends BaseAdapter {
private List list;
private Context context;
private static LayoutInflater inflater = null;
String [] cName;
String [] cDetail;
String [] created;
String [] cStatus;
TextView c_name,c_detail,c_date,c_status;
ArrayList<CourseModel> itemList;
Context mcontext;
public TrainerCourseAdapter(Context context,List list) {
mcontext = context;
itemList = (ArrayList<CourseModel>) list;
}
#Override
public int getCount() {
return itemList.size();
}
#Override
public Object getItem(int i) {
return i;
}
#Override
public long getItemId(int i) {
return i;
}
public void setItemList(ArrayList<CourseModel> itemList) {
this.itemList = itemList;
}
public class Holder
{
TextView c_name;
TextView c_detail;
TextView c_date ;
Button c_status;
}
#Override
public View getView(final int i, View view, ViewGroup viewGroup) {
Holder holder = new Holder();
View rowView;
rowView = inflater.inflate(R.layout.row_courses_list, viewGroup,false);
this.c_name = (TextView) rowView.findViewById(R.id.txt_courseName);
this.c_detail = (TextView) rowView.findViewById(R.id.txt_courseDetail);
this.c_date = (TextView) rowView.findViewById(R.id.txt_courseDate);
this.c_status = (Button) rowView.findViewById(R.id.btn_courseStatus);
System.out.println("Mudassir Don");
final CourseModel data = itemList.get(i);
this.c_name.setText(data.getTitle());
this.c_detail.setText(data.getDescription());
this.c_status.setText(data.getStatus());
this.c_date.setText(data.getId());
System.out.println(c_date);
rowView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(context, "You Clicked "+ cName[i], Toast.LENGTH_LONG).show();
}
});
return rowView;
}
}
code of activity is
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_course_outlines);
CourseOutlinesTask task = new CourseOutlinesTask();
task.execute("http://mantis.vu.edu.pk/bridging_the_gap/public/viewCourseOutlines");
mylist = task.viewResult();
listView = (ListView) findViewById(R.id.course_listView);
listView.setAdapter(new TrainerCourseAdapter(CourseOutlinesActivity.this,mylist ) {
});
You need to assign your custom Adapter to listView.
yourListView.setAdapter(yourAdapter);
In your case, inside onPostExecute method of CourseOutlinesTask you should write it.
TrainerCourseAdapter adapter = new TrainerCourseAdapter(context,postList);
listView = (ListView) findViewById(R.id.course_listView);
listview.setAdapter(adapter);
Hope this helps.
You need to write a interface and get response in your activity and set adapter to list view
like.
TrainerCourseAdapter adapter = new TrainerCourseAdapter(context,postList);
listView = (ListView) findViewById(R.id.course_listView);
listview.setAdapter(adapter);
You can use callBack interface to get itemArraylist data to your activity class.
After getting itemlist data in activity class you can set adapter to listview.
TrainerCourseAdapter adapter = new TrainerCourseAdapter(context, postList);
listView = (ListView) findViewById(R.id.course_listView);
listview.setAdapter(adapter);
// You can create interface in your CourseOutlinesClass with two method onSuccess() and onFailure() and in onPostExecute() send arraylist data using this interface to activity , then set adapter to fill data in listview.
Use the below code:-
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_course_outlines);
listView = (ListView) findViewById(R.id.course_listView);
new CourseOutlinesTask().execute("http://mantis.vu.edu.pk/bridging_the_gap/public/viewCourseOutlines");
}
and in postExecute of your AsyncTask setAdapter to listView
TrainerCourseAdapter adapter = new TrainerCourseAdapter(context,postList);
listView.setAdapter(adapter);
My recyclerView is not displaying the item views and dont no why, and I am able to get the data from the server but the recyclerView is just not populating my data with the ui.
Here is my Adapter class that binds the itemviews with the data :
public class AdapterBooking extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private LayoutInflater inflater;
List<Booking> data= Collections.emptyList();
Booking current ;
public AdapterBooking(Context context,List<Booking> data) {
this.context = context;
this.inflater= LayoutInflater.from(context);
this.data = data;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view=inflater.inflate(R.layout.containerbookings, parent,false);
MyHolder holder=new MyHolder(view);
return holder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
MyHolder myHolder = (MyHolder) holder;
current = data.get(position);
myHolder.txtAccommoName.setText(current.AccommoName);
myHolder.txtBookingDate.setText("Booking Date: " + current.BookingDate);
myHolder.txtBookingExpiry.setText("Booking Expiry: " + current.BookingDuration);
myHolder.txtBookngStatus.setText("Status " + current.AccredStatus);
myHolder.txtBookngStatus.setTextColor( ContextCompat.getColor(context, R.color.colorAccent));
Glide.with(context).load(R.drawable.the_yard_room)
.placeholder(R.drawable.ic_img_error)
.error(R.drawable.ic_img_error)
.into(myHolder.img);
}
#Override
public int getItemCount() {
return data.size();
}
class MyHolder extends RecyclerView.ViewHolder {
TextView txtAccommoName;
ImageView img;
TextView txtBookingDate;
TextView txtBookingExpiry;
TextView txtBookngStatus;
BootstrapButton btnCancel;
public MyHolder(View itemView) {
super( itemView );
txtAccommoName = (TextView)itemView.findViewById(R.id.textBookedAccommoName);
img= (ImageView) itemView.findViewById(R.id.imageBookedAccomo);
txtBookingDate = (TextView)itemView.findViewById(R.id.txtBookingDate);
txtBookingExpiry = (TextView)itemView.findViewById( R.id. txtBookingExpiry);
txtBookngStatus = (TextView)itemView.findViewById( R.id.txtBookingStatus );
btnCancel = (BootstrapButton)itemView.findViewById( R.id. btnCancelBookings);
}
Here is my Activity class that gets the data from the server:
public class BookingList extends AppCompatActivity {
List<Booking> data;
Booking booking;
RecyclerView recyclerViewBooking;
AdapterBooking mAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate( savedInstanceState );
setContentView( R.layout.activity_booking_list );
new Connect().execute();
}
private class Connect extends AsyncTask<String,String,String>
{
ProgressDialog load;
HttpURLConnection connection = null;
URL url = null;
String http = null;
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(BookingList.this);
int studID = settings.getInt("STUDENT_ID_BOOKING",0 );
public Connect() {
load = new ProgressDialog(BookingList.this);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
load.setMessage("Loading...");
load.setCancelable(false);
load.show();
}
#Override
protected String doInBackground(String... params) {
http = "http://192.168.42.197:5432/WCF/BookingServices.svc/getAllBookingsByStud/"+studID;
try {
url = new URL(http);
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
connection = (HttpURLConnection) url.openConnection();
connection.setReadTimeout(15000);
connection.setConnectTimeout(10000);
connection.setRequestMethod("GET");
connection.setRequestProperty("Accept", "Application/json");
connection.setDoInput(true);
} catch (IOException e) {
e.printStackTrace();
}
try {
int code = connection.getResponseCode();
System.out.println("Response: " + code);
if(code ==HttpURLConnection.HTTP_OK)
{
InputStream input = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
StringBuilder result = new StringBuilder();
String line = null;
while((line=reader.readLine()) != null)
{
result.append(line);
}
System.out.println(result.toString());
return (result.toString());
}else {
return("Unsuccessful");
}
} catch (IOException e) {
e.printStackTrace();
return e.toString();
}finally {
connection.disconnect();
}
}
#Override
protected void onPostExecute(String result) {
load.dismiss();
load.dismiss();
data= new ArrayList<>();
try {
JSONArray jsonArray = new JSONArray(result);
for (int i = 0; i < jsonArray.length();i++)
{
JSONObject jsonObject = jsonArray.getJSONObject(i);
JSONObject object = jsonObject.getJSONObject("Accommodation");
JSONObject objectStudent = jsonObject.getJSONObject("Student");
booking = new Booking();
booking.Name = objectStudent.getString("Name");
booking.Surname = objectStudent.getString("Surname");
booking.StudentNumber = objectStudent.getInt("StudentNumber");
booking.AccommoName = object.getString("AccommoName");
booking.AccredStatus = object.getString("AccredStatus");
booking.BookingDate = jsonObject.getString("BookingDate");
booking.BookingDuration = jsonObject.getString("BookingDuration");
booking.BookingStatus = jsonObject.getString( "BookingStatus" );
data.add(booking);
}
recyclerViewBooking = (RecyclerView)findViewById(R.id.listOfbooks);
mAdapter = new AdapterBooking(BookingList.this,data);
recyclerViewBooking.setAdapter(mAdapter);
recyclerViewBooking.setLayoutManager(new LinearLayoutManager(BookingList.this));
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(BookingList.this, e.toString(), Toast.LENGTH_LONG).show();
}
}
}
}
Check your Layout, make sure your RecyclerView isn't child of ScrollView. If you need that, you can use NestedScrollView.
If you make a breakpoint, your onBindViewHolder works?
Another thing yo can try:
There is a RecyclerView method: setHasStableIds(boolean).
#Override
public void setHasStableIds(boolean hasStableIds) {
return false;
}
Also, I think the context is wrong:
In activity:
private Activity getActivity {
return this;
}
In AsyncTask:
mAdapter = new AdapterBooking(getActivity().getApplicationContext(),data);
I hope this information help you.
Good luck.
Remove this:
MyHolder myHolder = (MyHolder) holder;
Instead do this: because I think there is no need to get another holder reference when you already have it on onBindViewHolder(..) method
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
current = data.get(position);
holder.txtAccommoName.setText(current.AccommoName);
holder.txtBookingDate.setText("Booking Date: " + current.BookingDate);
holder.txtBookingExpiry.setText("Booking Expiry: " + current.BookingDuration);
holder.txtBookngStatus.setText("Status " + current.AccredStatus);
holder.txtBookngStatus.setTextColor( ContextCompat.getColor(context, R.color.colorAccent));
Glide.with(context).load(R.drawable.the_yard_room)
.placeholder(R.drawable.ic_img_error)
.error(R.drawable.ic_img_error)
.into(holder.img);
}
Try this please and do let me know if it changes anything for you.
EDIT: As pointed out by #adnbsr as well in his comments you need to check this as well because it feels wrong instead you should have done this
extends RecyclerView.Adapter<AdapterBooking.MyHolder>
Fixed the problem. Im using shared preference to store data so I used the wrong key to get a value from the shared preference which before was causing the sharedpreference value to be initialized to zero.
private class getArticles extends AsyncTask<Void, Void, Void> {
String url;
getArticles(String paramUrl) {
this.url = paramUrl;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog = new ProgressDialog(App.this);
mProgressDialog.setMessage("Učitavanje artikala...");
mProgressDialog.setIndeterminate(false);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
arraylist = new ArrayList<>();
try {
Document document = Jsoup.connect(url).get();
Elements els = document.select("ul.category3 > li");
for (Element el : els) {
HashMap<String, String> map = new HashMap<>();
Elements slika = el.select("div.category3-image > a > img");
Elements naslov = el.select("div.category3-text > a.main-headline");
Element datum_noformat = el.select("div.category3-text > div.headlines-info > ul.headlines-info > li").first();
Element datum = datum_noformat.html(datum_noformat.html().replaceAll("Posted ", ""));
Elements desc = el.select("div.category3-text > p");
Elements link = el.select("div.category3-text > a.main-headline");
Element br_kom = el.select("div.category3-text > div.headlines-info > ul.headlines-info > li.comments-icon").first();
map.put("naslov", naslov.text());
map.put("datum", datum.text());
map.put("desc", desc.text());
map.put("ikona", slika.attr("src"));
map.put("link", link.attr("abs:href"));
map.put("brkom", br_kom.text());
arraylist.add(map);
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
listview = (ListView) findViewById(R.id.listview);
adapter = new ArtikliAdapter(App.this, arraylist);
listview.setAdapter(adapter);
mProgressDialog.dismiss();
}
I searched for a lot of codes for onlistview scrolling, but didn't know how to implement it. The problem is, when I call my asynctask, I have an url param,
like new getArticles("http://example.com").execute();
I want to implement an onscrolllistener, but it goes like this, my param is usually set to: http://www.example.com/category/categoryname/, so the second page goes like http://www.example.com/category/categoryname/page/2/, the third one goes http://www.example.com/category/categoryname/page/3/ and so on. Each page has got 7 items that need to be parsed.
How could I implement onscrolllistener, because of the url param?
Thanks in advance.
Base on this link, I have written following solution to add elements ( 30 elements at a time, i.e page size = 30) to listview asynchronously.
Create a class named EndlessListView as follows:
public class EndlessListView extends ListView implements OnScrollListener {
private View footer;
private boolean isLoading;
private EndlessListener listener;// listner
private EndlessAdapter endlessAdapter;// adapter.
private int maxNoOfElement;
public EndlessListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.setOnScrollListener(this);
}
public EndlessListView(Context context, AttributeSet attrs) {
super(context, attrs);
this.setOnScrollListener(this);
}
public EndlessListView(Context context) {
super(context);
this.setOnScrollListener(this);
}
public void setListener(EndlessListener listener) {
this.listener = listener;
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
if (getAdapter() == null)
return;
if (getAdapter().getCount() == 0 || getAdapter().getCount() <= 5)
return;
int l = visibleItemCount + firstVisibleItem;
if (l >= totalItemCount && !isLoading) {
// It is time to add new data. We call the listener
Log.e("LOAD", "DATA");
isLoading = true;
listener.loadData();
}
}
public void setMaxElemnt(int maxNoOfElement) {
this.maxNoOfElement = maxNoOfElement;
}
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
public void setLoadingView(int resId) {
LayoutInflater inflater = (LayoutInflater) super.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
footer = (View) inflater.inflate(resId, null);
this.addFooterView(footer);
}
public void setAdapter(EndlessAdapter adapter) {
super.setAdapter(adapter);
this.endlessAdapter = adapter;
}
public void addNewData(List<Integer> data) {
endlessAdapter.setData(data);
endlessAdapter.notifyDataSetChanged();
isLoading = false;
}
public static interface EndlessListener {
public void loadData();
}
}
After this we have to create the adapter for it,called
EndlessAdapter
public class EndlessAdapter extends BaseAdapter {
private List<Integer> mIntegers;
private Context context;
public EndlessAdapter(Context context) {
this.context = context;
}
public void setData(List<Integer> mIntegers) {
this.mIntegers = mIntegers;
}
#Override
public int getCount() {
if (mIntegers == null)
return 0;
return mIntegers.size();
}
#Override
public Integer getItem(int index) {
if (mIntegers == null) {
return null;
} else {
return mIntegers.get(index);
}
}
#Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
class ViewHolder {
TextView textView;
}
#Override
public View getView(int index, View view, ViewGroup viewGroup) {
ViewHolder holder;
if (view == null) {
holder = new ViewHolder();
view = ((LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE))
.inflate(R.layout.rows, viewGroup, false);
holder.textView = (TextView) view.findViewById(R.id.mtext);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
holder.textView.setText(getItem(index) + "");
return view;
}
}
Now in xml of the activity we could use EndlessListView(in com.example.stackoverflow package) as follows :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.example.stackoverflow.EndlessListView
android:id="#+id/endlessListView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
After this step we need to make following change in the MainActivity
public class MainActivity extends Activity implements EndlessListener {
private EndlessAdapter adapter;
private EndlessListView endlessListView;
private List<Integer> data;
private int gStartIndex = 30;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
endlessListView = (EndlessListView) findViewById(R.id.endlessListView);
adapter = new EndlessAdapter(this);
data = new ArrayList<Integer>();
endlessListView.setLoadingView(R.layout.footer);
// endlessListView.showFooter();
endlessListView.setListener(this);
endlessListView.setAdapter(adapter);
gStartIndex = 0;
fillData(gStartIndex);
}
private void fillData(int startIndex) {
new AsyncLoadData().execute(startIndex);
}
#Override
public void loadData() {
fillData(gStartIndex);
}
private class AsyncLoadData extends AsyncTask<Integer, Integer, Void> {
#Override
protected Void doInBackground(Integer... params) {
int gendIndex = params[0] + 30;
gStartIndex = gendIndex;
/***
* Here you could add your n/w code. To simulate the n/w comm. i am
* adding elements to list and making it sleep for few sec.
* */
for (int i = params[0]; i < gendIndex; i++) {
publishProgress(i);
}
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
data.add(values[0]);
}
#Override
protected void onPostExecute(Void result) {
endlessListView.addNewData(data);
}
}
}
This custom ScrollListView that I just found has OnBottomReachedListener which you can implement from your Activity or Fragment and receive events when user hits the bottom of the page. You would also need to track the current page and when bottom is hit to download the next page. The latest data should be added to your existing ArrayList and you should call notifyDataSetChanged() on your adapter so ListView can render the new data. You don't have to create new adapter, you just need to update the data source which is your ArrayList.
If you support orientation change you would must to save in onSaveInstanceState() your current page number so when Activity or Fragment is recreated it can continue from correct page. And you would have to keep the ArrayList data source safe of configuration changes because you don't want to downloaded it again. I would suggest using the Fragment with setRetainInstance() set to true to persist ArrayList.
Here is my custom code for keeping data around using RetainFragment:
/**
* A simple non-UI Fragment that stores a single Object
* and is retained over configuration changes.
*/
public class RetainFragment<E extends Object> extends Fragment {
/** Object for retaining. */
private E mObject;
/**
* Empty constructor as per the Fragment documentation
*/
public RetainFragment() {}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Make sure this Fragment is retained over a configuration change
setRetainInstance(true);
}
/**
* Store a single object in this Fragment.
*
* #param object The object to store
*/
public void setObject(E object) {
mObject = object;
}
/**
* Get the stored object.
*
* #return The stored object
*/
public E getObject() {
return mObject;
}
}
Example of RetainFragment usage in your Activity:
FragmentManager fm = getFragmentManager();
mRetainFragment = (RetainFragment<ArrayList>) fm.findFragmentByTag(RETAIN_FRAG);
if (mRetainFragment == null) {
mRetainFragment = new RetainFragment<>();
mRetainFragment.setObject(new ArrayList());
fm.beginTransaction().add(mRetainFragment, RETAIN_FRAG).commit();
}
ArrayList yourArrayList = mRetainFragment.getObject();
// Now your ArrayList is saved accrossed configuration changes
here what you want fist add onscrolllistner to listview
boolean loading_flage = false;
yourlistview.setOnScrollListener(new OnScrollListener() {
#Override
public void onScrollStateChanged(
AbsListView view,
int scrollState) {
// TODO Auto-generated method stub
}
#Override
public void onScroll(AbsListView view,
int firstVisibleItem,
int visibleItemCount,
int totalItemCount) {
final int lastItem = firstVisibleItem
+ visibleItemCount;
if ((lastItem == totalItemCount)
& loading_flage == false) {
//this to prevent the list to make more than one request in time
loading_flage = true;
//you can put the index for your next page here
loadMore(int page);
}
}
});
and then in loading more after loading the page set the loading with false and parse the data add it to the data that you aleardy have
//notify the adapter
adapter.notifyDataSetChanged();
loading_flage = false;
You can achieve by adding the scrolllistener on listview and check condition if list last visible item is last in ArrayList then call the asynctask with incremented page number and update the listview,mean while add the view on listview and after getting the result from server remove the loading more view from the listview like this -
AndroidListViewLoadMoreActivity.java
public class AndroidListViewLoadMoreActivity extends Activity {
ArrayList<Country> countryList;
MyCustomAdapter dataAdapter = null;
int page = 0;
boolean loadingMore = false;
View loadMoreView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ListView listView = (ListView) findViewById(R.id.listView1);
loadMoreView = ((LayoutInflater)this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE))
.inflate(R.layout.loadmore, null, false);
listView.addFooterView(loadMoreView);
//create an ArrayAdaptar from the String Array
countryList = new ArrayList<Country>();
dataAdapter = new MyCustomAdapter(this,
R.layout.country_info, countryList);
listView.setAdapter(dataAdapter);
//enables filtering for the contents of the given ListView
listView.setTextFilterEnabled(true);
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// When clicked, show a toast with the TextView text
Country country = (Country) parent.getItemAtPosition(position);
Toast.makeText(getApplicationContext(),
country.getCode(), Toast.LENGTH_SHORT).show();
}
});
listView.setOnScrollListener(new OnScrollListener(){
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {}
#Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
int lastInScreen = firstVisibleItem + visibleItemCount;
if((lastInScreen == totalItemCount) && !(loadingMore)){
String url = "http://10.0.2.2:8080/CountryWebService" +
"/CountryServlet";
grabURL(url);
}
}
});
String url = "http://example.com";
grabURL(url);
}
public void grabURL(String url) {
Log.v("Android Spinner JSON Data Activity", url);
new GrabURL().execute(url);
}
private class GrabURL extends AsyncTask<String, Void, String> {
private static final int REGISTRATION_TIMEOUT = 3 * 1000;
private static final int WAIT_TIMEOUT = 30 * 1000;
private final HttpClient httpclient = new DefaultHttpClient();
final HttpParams params = httpclient.getParams();
HttpResponse response;
private String content = null;
private boolean error = false;
private ProgressDialog dialog =
new ProgressDialog(AndroidListViewLoadMoreActivity.this);
protected void onPreExecute() {
dialog.setMessage("Getting your data... Please wait...");
dialog.show();
}
protected String doInBackground(String... urls) {
String URL = null;
loadingMore = true;
try {
URL = urls[0];
HttpConnectionParams.setConnectionTimeout(params, REGISTRATION_TIMEOUT);
HttpConnectionParams.setSoTimeout(params, WAIT_TIMEOUT);
ConnManagerParams.setTimeout(params, WAIT_TIMEOUT);
HttpPost httpPost = new HttpPost(URL);
//add name value pair for the country code
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("page",String.valueOf(page)));
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
response = httpclient.execute(httpPost);
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
content = out.toString();
} else{
//Closes the connection.
Log.w("HTTP1:",statusLine.getReasonPhrase());
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
Log.w("HTTP2:",e );
content = e.getMessage();
error = true;
cancel(true);
} catch (IOException e) {
Log.w("HTTP3:",e );
content = e.getMessage();
error = true;
cancel(true);
}catch (Exception e) {
Log.w("HTTP4:",e );
content = e.getMessage();
error = true;
cancel(true);
}
return content;
}
protected void onCancelled() {
dialog.dismiss();
Toast toast = Toast.makeText(AndroidListViewLoadMoreActivity.this,
"Error connecting to Server", Toast.LENGTH_LONG);
toast.setGravity(Gravity.TOP, 25, 400);
toast.show();
}
protected void onPostExecute(String content) {
dialog.dismiss();
Toast toast;
if (error) {
toast = Toast.makeText(AndroidListViewLoadMoreActivity.this,
content, Toast.LENGTH_LONG);
toast.setGravity(Gravity.TOP, 25, 400);
toast.show();
} else {
displayCountryList(content);
}
}
}
private void displayCountryList(String response){
JSONObject responseObj = null;
try {
Gson gson = new Gson();
responseObj = new JSONObject(response);
JSONArray countryListObj = responseObj.getJSONArray("countryList");
//countryList = new ArrayList<Country>();
if(countryListObj.length() == 0){
ListView listView = (ListView) findViewById(R.id.listView1);
listView.removeFooterView(loadMoreView);
}
else {
for (int i=0; i<countryListObj.length(); i++){
//get the country information JSON object
String countryInfo = countryListObj.getJSONObject(i).toString();
//create java object from the JSON object
Country country = gson.fromJson(countryInfo, Country.class);
//add to country array list
countryList.add(country);
dataAdapter.add(country);
}
page++;
dataAdapter.notifyDataSetChanged();
loadingMore = false;
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
Make MyCustomAdapter.java as adapter
private class MyCustomAdapter extends ArrayAdapter<Country> {
private ArrayList<Country> countryList;
public MyCustomAdapter(Context context, int textViewResourceId,
ArrayList<Country> countryList) {
super(context, textViewResourceId, countryList);
this.countryList = new ArrayList<Country>();
this.countryList.addAll(countryList);
}
private class ViewHolder {
TextView code;
TextView name;
TextView continent;
TextView region;
}
public void add(Country country){
Log.v("AddView", country.getCode());
this.countryList.add(country);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
Log.v("ConvertView", String.valueOf(position));
if (convertView == null) {
LayoutInflater vi = (LayoutInflater)getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.country_info, null);
holder = new ViewHolder();
holder.code = (TextView) convertView.findViewById(R.id.code);
holder.name = (TextView) convertView.findViewById(R.id.name);
holder.continent = (TextView) convertView.findViewById(R.id.continent);
holder.region = (TextView) convertView.findViewById(R.id.region);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Country country = this.countryList.get(position);
holder.code.setText(country.getCode());
holder.name.setText(country.getName());
holder.continent.setText(country.getContinent());
holder.region.setText(country.getRegion());
return convertView;
}
}
}
Create Country.Java as pojo -
public class Country {
String code = null;
String name = null;
String continent = null;
String region = null;
Double lifeExpectancy = null;
Double gnp = null;
Double surfaceArea = null;
int population = 0;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getContinent() {
return continent;
}
public void setContinent(String continent) {
this.continent = continent;
}
public String getRegion() {
return region;
}
public void setRegion(String region) {
this.region = region;
}
public Double getLifeExpectancy() {
return lifeExpectancy;
}
public void setLifeExpectancy(Double lifeExpectancy) {
this.lifeExpectancy = lifeExpectancy;
}
public Double getGnp() {
return gnp;
}
public void setGnp(Double gnp) {
this.gnp = gnp;
}
public Double getSurfaceArea() {
return surfaceArea;
}
public void setSurfaceArea(Double surfaceArea) {
this.surfaceArea = surfaceArea;
}
public int getPopulation() {
return population;
}
public void setPopulation(int population) {
this.population = population;
}
}
Create main.xml for main layout
<?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="fill_parent"
android:orientation="vertical">
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content" android:padding="10dp"
android:text="#string/some_text" android:textSize="20sp" />
<ListView android:id="#+id/listView1" android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
Create country_info.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="6dip" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="Code: "
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/textView1"
android:layout_below="#+id/textView1"
android:text="Name: "
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/textView2"
android:layout_below="#+id/textView2"
android:text="Continent: "
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/textView3"
android:layout_below="#+id/textView3"
android:text="Region: "
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/continent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/textView3"
android:layout_alignBottom="#+id/textView3"
android:layout_toRightOf="#+id/textView3"
android:text="TextView" />
<TextView
android:id="#+id/region"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/textView4"
android:layout_alignBottom="#+id/textView4"
android:layout_alignLeft="#+id/continent"
android:text="TextView" />
<TextView
android:id="#+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/textView3"
android:layout_toRightOf="#+id/textView3"
android:text="TextView" />
<TextView
android:id="#+id/code"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/textView2"
android:layout_alignLeft="#+id/name"
android:text="TextView" />
</RelativeLayout>
Footer View Text - loadmore.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:gravity="center_horizontal"
android:padding="3dp"
android:layout_height="fill_parent">
<TextView
android:id="#id/android:empty"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:gravity="center"
android:padding="5dp"
android:text="Loading more data..."/>
</LinearLayout>
Don't forget to mention internet permission with -
<uses-permission android:name="android.permission.INTERNET" />
First, you need a OnScrollListener method like this:
private OnScrollListener onScrollListener() {
return new OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
int threshold = 1;
int count = listView.getCount();
if (scrollState == SCROLL_STATE_IDLE) {
if (listView.getLastVisiblePosition() >= count - threshold && pageCount < 2) {
Log.i(TAG, "loading more data");
// Execute LoadMoreDataTask AsyncTask
//It reached ListView bottom
getDataFromUrl(url_page2);
}
}
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
int totalItemCount) {
}
};
}
set List View scroll listener by listView.setOnScrollListener(onScrollListener());
I have a full tutorial post HERE! You can visit it!
I have an app which downloads YouTube JSON data. The code works perfectly in a desktop app, but not in android (the list is null when trying to iterate through it). Here's my code which matters:
public String DownloadJSONData(){
BufferedReader reader = null;
String webc = "";
try{
URL url = new URL("http://gdata.youtube.com/feeds/api/users/thecovery/uploads?v=2&alt=json");
reader = new BufferedReader(new InputStreamReader(url.openStream()));
StringBuffer buffer = new StringBuffer();
int read;
char[] chars = new char[1024];
while((read = reader.read(chars)) != -1){
buffer.append(chars,0,read);
}
webc = buffer.toString();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
return webc;
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println(webc);
return webc;
}
public void GetData() throws JSONException {
JSONObject obj = new JSONObject(DownloadJSONData());
JSONArray feed = obj.getJSONObject("feed").getJSONArray("entry");
for(int i = 0; i < feed.length(); i++){
EPISODE_NAME.add(feed.getJSONObject(i).getJSONObject("title").getString("$t"));
EPISODE_LINK.add(feed.getJSONObject(i).getJSONArray("link").getJSONObject(0).getString("href"));
}
ListView episodes = (ListView) findViewById(R.id.episodeChooser);
ArrayAdapter<String> episodesSource = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,EPISODE_NAME);
}
}
In the onCreate method, I call the GetData() method, and I try to set the adapter to the ListView from the EPISODE_NAME ArrayList, but it's null. I also tried to set the adapter after the method, in onCreate, but no luck. Anyone can help?
It works fine
Add Below permission in Manifest.xml
<uses-permission android:name="android.permission.INTERNET"/>
ManiActivity.java
public class MainActivity extends Activity {
private ListView listView;
private List<FeedsDTO> feedsList = new ArrayList<FeedsDTO>();
private FeedsDTO dto = null;
private BackgroundThread backgroundThread;
private CustomAdapter customAdapter = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listview);
backgroundThread = new BackgroundThread();
backgroundThread.execute();
}
private void setListViewAdapter(){
customAdapter = new CustomAdapter(this, R.layout.listitem, feedsList);
listView.setAdapter(customAdapter);
}
private class BackgroundThread extends AsyncTask<Void, Void, String> {
private ProgressDialog progressBar = null;
#Override
protected void onPreExecute() {
super.onPreExecute();
progressBar = new ProgressDialog(MainActivity.this);
progressBar.setCancelable(false);
progressBar.show();
}
#Override
protected String doInBackground(Void... params) {
BufferedReader reader = null;
String webc = "";
try{
URL url = new URL("http://gdata.youtube.com/feeds/api/users/thecovery/uploads?v=2&alt=json");
reader = new BufferedReader(new InputStreamReader(url.openStream()));
StringBuffer buffer = new StringBuffer();
int read;
char[] chars = new char[1024];
while((read = reader.read(chars)) != -1){
buffer.append(chars,0,read);
}
webc = buffer.toString();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
return webc;
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println(webc);
return webc;
}
#Override
protected void onPostExecute(String result) {
JSONObject obj;
try {
obj = new JSONObject(result);
JSONArray feed = obj.getJSONObject("feed").getJSONArray("entry");
Log.i("=======", "========="+feed.length());
for(int i = 0; i < feed.length(); i++){
dto = new FeedsDTO();
dto.setName(feed.getJSONObject(i).getJSONObject("title").getString("$t"));
dto.setLink(feed.getJSONObject(i).getJSONArray("link").getJSONObject(0).getString("href"));
feedsList.add(dto);
dto = null;
}
Log.i("=======LIst Size", "========="+feedsList.size());
progressBar.dismiss();
setListViewAdapter();
} catch (JSONException e) {
e.printStackTrace();
}
super.onPostExecute(result);
}
}
}
CustomAdapter.java
public class CustomAdapter extends ArrayAdapter<FeedsDTO>{
private LayoutInflater inflater;
private int layoutID;
public CustomAdapter(Context cntx, int resource, List<FeedsDTO> objects) {
super(cntx, resource, objects);
this.inflater =(LayoutInflater) cntx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.layoutID = resource;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
try {
ViewHolder holder = null;
if (convertView == null) {
convertView = inflater.inflate(layoutID, null);
holder = new ViewHolder();
holder.NameTV = (TextView) convertView.findViewById(R.id.textview);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
FeedsDTO feedsDTO = getItem(position);
holder.NameTV.setText(feedsDTO.getName());
feedsDTO = null;
} catch (Exception e) {
e.printStackTrace();
}
return convertView;
}
private class ViewHolder{
TextView NameTV;
}
}
FeedsDTO.java
public class FeedsDTO {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
private String link;
}
listitem.xlm:-
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/textview"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</TextView>
I hope this code will work perfectly
Most apps include several different activities that allow the user to
perform different actions. Whether an activity is the main activity
that's created when the user clicks your app icon or a different
activity that your app starts in response to a user action, the system
creates every new instance of Activity by calling its onCreate()
method.
You must implement the onCreate() method to perform basic application
startup logic that should happen only once for the entire life of the
activity. For example, your implementation of onCreate() should define
the user interface and possibly instantiate some class-scope
variables.
For example, the following example of the onCreate() method shows some
code that performs some fundamental setup for the activity, such as
declaring the user interface (defined in an XML layout file), defining
member variables, and configuring some of the UI.
You are basically mixing stuff left and right. First create your Interface in the onCreate() and do the logic in onStart().
You should read the android lifecycle. See here