in my project it is necessary to implement loading data from ms sql procedure into listview. I created my listview layout, configured the adapter according to this example - https://github.com/codepath/android_guides/wiki/Using-an-ArrayAdapter-with-ListView.
But I ran into a problem - no new lines are created in my listview, but the first one is overwritten.
Here is my code:
Method to call sql procedure and populate listview
public void fillVagonList ()
{
ResultSet rs = null;
PreparedStatement ps = null;
try {
ConnectToSql connectToSql = new ConnectToSql();
SqlConnect = connectToSql.connect();
if (SqlConnect != null)
{
String SPsql = "EXEC mobile3_GETCARLIST ?,?,?,?";
ps = SqlConnect.prepareStatement(SPsql);
ps.setEscapeProcessing(true);
ps.setQueryTimeout(1000);
ps.setInt(1, LoginActivity.SesId);
ps.setString(2, EquipmentWagon.deadend);
ps.setString(3, EquipmentWagon.sectorName);
ps.setInt(4, EquipmentWagon.operID);
rs = ps.executeQuery();
vagonNumberList = new ArrayList<String>();
vagonNatList = new ArrayList<String>();
vagonLengthList = new ArrayList<String>();
//completeList = new ArrayList<String>();
while (rs.next())
{
Vagon vagon = new Vagon(rs.getString(2),rs.getString(1),rs.getString(5));
ArrayList<Vagon> vagonArrayList = new ArrayList<Vagon>();
VagonAdapter adapter = new VagonAdapter(getContext(),vagonArrayList);
lvVagonList.setAdapter(adapter);
adapter.addAll(vagon);
}
} else {
ConnectionResult = "Check Connection";
}
} catch (SQLException se)
{
System.out.println("Error al ejecutar SQL" + se.getMessage());
se.printStackTrace();
throw new IllegalArgumentException("Error al ejecutar SQL: " + se.getMessage());
} finally
{
try
{
rs.close();
ps.close();
SqlConnect.close();
}
catch (SQLException ex)
{
ex.printStackTrace();
}
}
}
Vagon class:
public class Vagon {
public String carNumber;
public String natList;
public String vagonLength;
public Vagon(String carNumber, String natList,String vagonLength)
{
this.carNumber = carNumber;
this.natList = natList;
this.vagonLength = vagonLength;
}
}
VagonAdapter class:
public class VagonAdapter extends ArrayAdapter<Vagon> {
public VagonAdapter(Context context, ArrayList<Vagon> vagons) {
super(context, 0, vagons);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
Vagon vagon = getItem(position);
// Check if an existing view is being reused, otherwise inflate the view
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.adapter_vagon_view, parent, false);
}
// Lookup view for data population
TextView tvNomVag = (TextView) convertView.findViewById(R.id.tvNomVag);
TextView tvNatList = (TextView) convertView.findViewById(R.id.tvNatList);
TextView tvCarLength = (TextView) convertView.findViewById(R.id.tvCarLength);
// Populate the data into the template view using the data object
tvNomVag.setText(vagon.carNumber);
tvNatList.setText(vagon.natList);
tvCarLength.setText(vagon.vagonLength);
// Return the completed view to render on screen
return convertView;
}
}
What do I need to do so that the first line is not overwritten, but a new one is added? Help me out, i'm stucked on this moment. Thanks.
i modified this part in method :
ArrayList<Vagon> vagonArrayList = new ArrayList<>();
for (int i = 0; i < vagonNumberList.size(); i++) {
try {
vagonArrayList.add(new Vagon(vagonNumberList.get(i),vagonNatList.get(i),vagonLengthList.get(i)));
} catch (Exception e) {
e.printStackTrace();
}
}
VagonAdapter adapter = new VagonAdapter(getContext(),vagonArrayList);
lvVagonList.setAdapter(adapter);
Related
Currently, I am trying to create a mobile application in Android Studio which allows the user to enter an ISBN number and when the search button is clicked, it will then search a CSV in the raw folder and return results of that ISBN query. This CSV file includes all other information which is associated with that number separated by commas. Currently its returns all results of the CSV file ordered into edit text fields on the user interface. How can I change my code to only return the specific result which I want?
This is the readFile class:
public class readFile {
InputStream inputStream;
public readFile(InputStream inputStream){
this.inputStream = inputStream;
}
public List<String[]> read(){
List<String[]> resultList = new ArrayList<String[]>();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
try {
String csvLine;
while ((csvLine = reader.readLine()) != null) {
String[] row = csvLine.split(",");
resultList.add(row);
}
}
catch (IOException ex) {
throw new RuntimeException("Error in reading CSV file: "+ex);
}
finally {
try {
inputStream.close();
}
catch (IOException e) {
throw new RuntimeException("Error while closing input stream: "+e);
}
}
return resultList;
}
}
The itemArrayAdapter class:
public class ItemArrayAdapter extends ArrayAdapter<String[]> {
private List<String[]> scoreList = new ArrayList<String[]>();
static class ItemViewHolder {
EditText title, publicationPlace,publicationDate,edition,author;
}
public ItemArrayAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
}
#Override
public void add(String[] object) {
scoreList.add(object);
super.add(object);
}
#Override
public int getCount() {
return this.scoreList.size();
}
#Override
public String[] getItem(int index) {
return this.scoreList.get(index);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ItemViewHolder viewHolder;
if (row == null) {
LayoutInflater inflater = (LayoutInflater) this.getContext().
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.item_layout, parent, false);
viewHolder = new ItemViewHolder();
viewHolder.title = (EditText) row.findViewById(R.id.title);
viewHolder.publicationDate = (EditText) row.findViewById(R.id.publicationDate);
viewHolder.publicationPlace = (EditText) row.findViewById(R.id.publicationPlace);
viewHolder.edition = (EditText) row.findViewById(R.id.edition);
viewHolder.author = (EditText) row.findViewById(R.id.authors);
row.setTag(viewHolder);
} else {
viewHolder = (ItemViewHolder)row.getTag();
}
String[] isbn = getItem(position);
viewHolder.title.setText(isbn[1]);
viewHolder.publicationDate.setText(isbn[2]);
viewHolder.publicationPlace.setText(isbn[3]);
viewHolder.edition.setText(isbn[4]);
viewHolder.author.setText(isbn[5]);
return row;
}
}
[...code...]
String[] row = csvLine.split(",");
// Add the check as shown here:
for ( int col = 0; col < row.length; col++ ) { // this could be avoided
if ( row[col].compareTo(ISBN_string) == 0 )
resultList.add(row);
}
// Maby if you know the column no. you can get away without the iteration
// resultList.add(row); <-- this is now obsolete
[...more code...]
Please help me out
I am fetching image from a JSON API to my android app for each item in my arraylist. The images are fetching correctly, but instead of setting only the image that is meant for each list item, it is looping and interchanging all the images in all the list on one item and all the list items respectively, thereby making the image in each list item to be changing to different images in seconds.
See the JSON file
{ "data":[
{
"sno":1,
"id":"3",
"title":"This Is Great Again",
"desc":"The details of how a UUID is generated are determined by the device manufacturer and are specific to the device's platform or model.The details of...",
"free":"Yes",
"image":"http:\/\/app-web.moneyacademy.ng\/uploads\/145277f3d0499ee8e0dafbac384ca9b4.jpg",
"date_added":"2017-10-12 10:26PM",
"no_comment":3,
"comments":[ ]
},
{
"sno":2,
"id":"6",
"title":"Money Makes The World Go Round",
"desc":"On this realm, nothing works without money. You need to get some of it or else you'll be grounded.",
"free":"Yes",
"image":"http:\/\/app-web.moneyacademy.ng\/uploads\/546a4c29a94f3d70ae9a075ce8afcc6b.jpg",
"date_added":"2018-02-18 10:06AM",
"no_comment":0,
"comments":[ ]
},
{
"sno":3,
"id":"7",
"title":"No One Is Destined To Be Poor",
"desc":"You will not be poor.",
"free":"Yes",
"image":"http:\/\/app-web.moneyacademy.ng\/uploads\/8f19b9cebd1ca4dec74fafcfe23ae0f0.jpg",
"date_added":"2018-02-18 01:03PM",
"no_comment":0,
"comments":[ ]
},
{
"sno":4,
"id":"8",
"title":"What Is Your Money?",
"desc":"Understand the true definition of your money.",
"free":"Yes",
"image":"http:\/\/app-web.moneyacademy.ng\/uploads\/49b35ffb5cabcb7e01dab2d452ec6025.jpg",
"date_added":"2018-02-18 01:30PM",
"no_comment":0,
"comments":[ ]
},
Here is my code for fetching each item and the image
private static ArrayList<nauget> extractFeatureFromJson(String freeNaugetJson) {
// If the JSON string is empty or null, then return early.
if (TextUtils.isEmpty(freeNaugetJson)) {
return null;
}
ArrayList<nauget> naugets = new ArrayList<nauget>();
try {
JSONObject baseJsonResponse = new JSONObject(freeNaugetJson);
JSONArray dataArray = baseJsonResponse.getJSONArray("data");
// If there are results in the data array
for (int i = 0; i < dataArray.length(); i++){
String title = dataArray.getJSONObject(i).getString("title");
String body = dataArray.getJSONObject(i).getString("desc");
String totalComments = dataArray.getJSONObject(i).getString("no_comment");
String image = dataArray.getJSONObject(i).getString("image");
int id = dataArray.getJSONObject(i).getInt("id");
ArrayList<Comment> comments = new ArrayList<Comment>();
//fetch each comment detail
if (Integer.parseInt(totalComments) > 0) {
JSONArray commentArray = dataArray.getJSONObject(i).getJSONArray("comments");
for (int j = 0; j < commentArray.length(); j++) {
String userName = commentArray.getJSONObject(j).getString("userName");
String comment_image = commentArray.getJSONObject(j).getString("userPhoto");
String comment = commentArray.getJSONObject(j).getString("comment");
String date = commentArray.getJSONObject(j).getString("date_commented");
comments.add(new Comment(userName, comment_image, comment, date));
}
}
// Create a new nauget object
naugets.add(new nauget(title, body, image, totalComments, comments, id));
}
} catch (JSONException e) {
Log.e(LOG_TAG, "Problem parsing the nauget JSON results", e);
}
return naugets;
}
Here is my custom adapter code where am setting the image and its text data for each list item.
public class NaugetAddapter extends ArrayAdapter<nauget> {
ArrayList<nauget> naugets;
private nauget currentNauget;
private ImageView naugetImage;
private TextView naugetTitle;
private TextView naugetBody;
private TextView commentCount;
public NaugetAddapter(#NonNull Context context, ArrayList<nauget> naugets) {
super(context, 0, naugets);
}
#NonNull
#Override
public View getView(final int position, #Nullable View convertView, #NonNull ViewGroup parent) {
//check if the convert view is null and inflate the view
if (convertView == null){
convertView = LayoutInflater.from(getContext()).inflate(R.layout.free_nauget_item, parent, false);
}
currentNauget = (nauget) getItem(position);
//find the nauget title textView and set the text
naugetTitle = (TextView) convertView.findViewById(R.id.nauget_title);
naugetTitle.setText(currentNauget.getNauget_title());
//find the nauget body textView and set the text
naugetBody = (TextView) convertView.findViewById(R.id.nauget_body);
naugetBody.setText(currentNauget.getNauget_body());
//set the nauget total comment count
commentCount = (TextView) convertView.findViewById(R.id.comment_count);
commentCount.setText(currentNauget.getNaugetTotalComments());
//set the comment text
TextView commentText = (TextView) convertView.findViewById(R.id.comment_text);
commentText.setText(currentNauget.getNaugetCommentText());
//set the nauget image
naugetImage = (ImageView) convertView.findViewById(R.id.nauget_image);
new DownloadImageTask().execute(currentNauget.getImageUrl());
//set the share icon
ImageView shareIcon = (ImageView) convertView.findViewById(R.id.share_icon);
shareIcon.setImageResource(currentNauget.getNaugetShareIcon());
//set share functionality on the share icon
shareIcon.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_SUBJECT, "My App");
shareIntent.putExtra(Intent.EXTRA_TEXT,
naugetTitle.getText()
+ "\n" + naugetBody.getText()
+ "\n" + naugetImage.getDrawable());
startActivity(getContext(), Intent.createChooser(shareIntent, "Share via"), null);
}
});
return convertView;
}
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// mLoadingIndicator.setVisibility(View.VISIBLE);
}
protected Bitmap doInBackground(String... urls) {
Bitmap image = null;
HttpURLConnection urlConnection = null;
try {URL url = new URL(urls[0]);
urlConnection = (HttpURLConnection) url.openConnection();
int statusCode = urlConnection.getResponseCode();
if (statusCode != 200) {
return null;
}
InputStream inputStream = urlConnection.getInputStream();
if (inputStream != null) {
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
return bitmap;
}
} catch (Exception e) {
urlConnection.disconnect();
Log.e("Error", e.getMessage());
e.printStackTrace();
}finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
return null;
}
protected void onPostExecute(Bitmap result) {
// mLoadingIndicator.setVisibility(View.INVISIBLE);
naugetImage.setImageBitmap(result);
}
}
#NonNull
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
ArrayList<nauget> filteredResults = new ArrayList<>();
FilterResults results = new FilterResults();
results.values = filteredResults;
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
}
};
}
void setFilter(ArrayList<nauget> listItem){
naugets = new ArrayList();
naugets.addAll(listItem);
notifyDataSetChanged();
}
}
This should solve the issue! you are trying everything fine but you have the comment ArrayList inside of a loop getting instantiated each time newly just put it before the outer loop as I did here and the error should go! TRY IT
try {
JSONObject baseJsonResponse = new JSONObject(freeNaugetJson);
JSONArray dataArray = baseJsonResponse.getJSONArray("data");
//put it here so you won't get a new array for each comment in the loop
**ArrayList<Comment> comments = new ArrayList<Comment>();**
// If there are results in the data array
for (int i = 0; i < dataArray.length(); i++){
String title = dataArray.getJSONObject(i).getString("title");
String body = dataArray.getJSONObject(i).getString("desc");
String totalComments = dataArray.getJSONObject(i).getString("no_comment");
String image = dataArray.getJSONObject(i).getString("image");
int id = dataArray.getJSONObject(i).getInt("id");
//here after every comment check its making a new comment ArrayList for each comment and filling it out so this can be the cause of the bug! bcz its in the loop
// ArrayList<Comment> comments = new ArrayList<Comment>();
//fetch each comment detail
if (Integer.parseInt(totalComments) > 0) {
JSONArray commentArray = dataArray.getJSONObject(i).getJSONArray("comments");
for (int j = 0; j < commentArray.length(); j++) {
String userName = commentArray.getJSONObject(j).getString("userName");
String comment_image = commentArray.getJSONObject(j).getString("userPhoto");
String comment = commentArray.getJSONObject(j).getString("comment");
String date = commentArray.getJSONObject(j).getString("date_commented");
comments.add(new Comment(userName, comment_image, comment, date));
}
}
// Create a new nauget object
naugets.add(new nauget(title, body, image, totalComments, comments, id));
}
} catch (JSONException e) {
Log.e(LOG_TAG, "Problem parsing the nauget JSON results", e);
}
return naugets;
So I am trying to implement a Cursor to my class so i can populate my datagrid (not sure if that is the right way to do it when i need to use callable for SP and prepared statement) which i made from this guide here but i gets a
DataGridActivity.Itemnumber is not abstract and does not override abstract method respond(Bundle) in Cursor
i am not sure how to implement the abstract method here as i
normaly use getstring methode for my prepared statements wonder if there is somehow i could do that instead to populate my grid instead of using the Cursor
public class Itemnumber extends AsyncTask<String,String,String> implements Cursor {
String z = "";
#Override
protected void onPreExecute() {
}
#Override
protected void onPostExecute(String r) {
}
#Override
protected String doInBackground(String... params) {
try {
Connection con = connectionClass.CONN();
if (con == null) {
z = "Error in connection with SQL server";
} else {
PreparedStatement preparedStatement = null;
String sqli = "select ID,ItemNumber,Trashed,Sold from [file].[Item] where [ItemNumber] =?";
preparedStatement = con.prepareStatement(sqli);
preparedStatement.setString(1, "test");
ResultSet rs = preparedStatement.executeQuery();
if (rs.next()) {
} else {
}
}
} catch (Exception ex) {
z = "Exceptions";
}
return z;
}
#Override
public Bundle respond(Bundle extras){
moveToFirst();
return Bundle.EMPTY;
}
}
My Datagrid activity class
Cursor csr = new Itemnumber();
//create DataTable object
DataTable dtDataSource = new DataTable();
//define column
dtDataSource.addAllColumns(new String[]{"column_1", "column_2","column_3", "column_4});
//create DataRow
DataTable.DataRow drRow;
//populate data from cursor into DataSource
if(csr.moveToFirst()){
do{
drRow = dtDataSource.newRow();
drRow.set("column_1", csr.getString(csr.getColumnIndex("field_1")));
drRow.set("column_2", csr.getString(csr.getColumnIndex("field_2")));
drRow.set("column_2", csr.getString(csr.getColumnIndex("field_3")));
drRow.set("column_4", csr.getString(csr.getColumnIndex("field_4")));
dtDataSource.add(drRow);
} while(csr.moveToNext());
csr.close();
}
/**
* Prepare the DataGrid
*/
//initialize DataGrid
DataGrid dg = (DataGrid)findViewById(R.id.datagrid);
//define column style, bond each DataGrid column by DataTable column
dg.addColumnStyles(new DataGrid.ColumnStyle[]{
new DataGrid.ColumnStyle(getString(R.string.ID), "column_1", 80),
new DataGrid.ColumnStyle(getString(R.string.ItemNumber), "column_2", 120),
new DataGrid.ColumnStyle(getString(R.string.Trashed), "column_3", 100),
new DataGrid.ColumnStyle(getString(R.string.Sold), "column_4", 150)
});
//set the DataTable as source
dg.setDataSource(dtDataSource);
//generate the DataGrid
dg.refresh();
You must override last method in Itemnumber class.
This method is in interface Cursor, and named: respond(Bundle)
So, if Your class Itemnumber implemented Cursor, please add
#Override
Bundle respond(Bundle extras){
return Bundle.EMPTY;
}
and implemented, what Your method must return
I figured out how to do it with just use my prepaered statement.
As implementing all the abstract methodes and interfaces didn't seemed to be anything near logical
public class DataGridActivity extends Activity {
/** Called when the activity is first created. */
ConnectionClass connectionClass;
//define column
DataTable.DataRow drRow;
DataTable dtDataSource = new DataTable();
Button btnsearch;
DataGrid dg;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.datagridt);
dg = (DataGrid)findViewById(R.id.datagrid);
btnsearch = (Button) findViewById(R.id.btnsearch);
connectionClass = new ConnectionClass(this.getApplicationContext());
/**
* Prepare the DataGrid
*/
//initialize DataGrid
//define column style, bond each DataGrid column by DataTable column
dg.addColumnStyles(new DataGrid.ColumnStyle[]{
new DataGrid.ColumnStyle(getString(R.string.dito_nr), "column_1", 80),
new DataGrid.ColumnStyle(getString(R.string.Biltype), "column_2", 120),
new DataGrid.ColumnStyle(getString(R.string.kort_nr), "column_3", 100),
new DataGrid.ColumnStyle(getString(R.string.Del_Type), "column_4", 150)
});
}
public class Itemnumber extends AsyncTask<String,String,String> {
String z = "";
#Override
protected void onPreExecute() {
dtDataSource.addAllColumns(new String[]{"column_1", "column_2","column_3", "column_4"});
drRow = dtDataSource.newRow();
dtDataSource.add(drRow);
dg.setDataSource(dtDataSource);
dg.refresh();
}
#Override
protected void onPostExecute(String r) {
}
#Override
protected String doInBackground(String... params) {
try {
Connection con = connectionClass.CONN();
if (con == null) {
z = "Error in connection with SQL server";
} else {
PreparedStatement preparedStatement = null;
String sqli = "select ID,ItemNumber,Trashed,Sold from [file].[Item]";
preparedStatement = con.prepareStatement(sqli);
ResultSet rs = preparedStatement.executeQuery();
if (rs.next()) {
//create DataRow
drRow.set("column_1", rs.getString(1));
drRow.set("column_2", rs.getString(2));
drRow.set("column_3", rs.getString(3));
drRow.set("column_4", rs.getString(4));
} else {
}
}
} catch (Exception ex) {
z = "Exceptions";
}
return z;
}
}
public void btnsearch (View view) {
// TODO Auto-generated method stub
Itemnumber item = new Itemnumber();
item.execute("");
}
}
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.
I am trying to load an array of items into a listview from MySQL. Based on the data, if 'no_sms_service' = 1 then I want to change only that item's background color. I have tried to override the view but it doesn't specifically change the item. It changes all of the items. What am I doing wrong?
public void loadReservations() {
ListView lv = (ListView) this.findViewById(R.id.waitingList);
String url = "jdbc:mysql://"+dbURL+":"+dbPort+"/"+dbDatabase+"";
String user = dbUser;
String pass = dbPass;
List<String> waitingList = new ArrayList<String>();
try {
StrictMode.ThreadPolicy policy =
new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection(url, user, pass);
Statement st = con.createStatement();
final ResultSet rs = st.executeQuery("SELECT cust_name, reserve_Date, Seat_prefer, reserve_people, Notes, no_sms_service FROM seat_reserve WHERE reserve_Close=0 && DATE(reserve_Date) = DATE(NOW()) ORDER BY reserve_Date ASC");
ResultSetMetaData rsmd = rs.getMetaData();
String result;
while (rs.next()) {
String myTimestamp = rs.getTimestamp(2).toString();
DateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.S");
Date date = inputFormat.parse(myTimestamp);
DateFormat outputFormat = new SimpleDateFormat("hh:mm a");
String outputString = outputFormat.format(date);
result = "\n" +"Name: " + rs.getString(1)
+ "\n" + "Reservation Time: " + outputString
+ "\n" + "Preferred Area: " + rs.getString(3)
+ "\n" + "Guests: " + rs.getString(4)
+ "\n" + "Notes: " + rs.getString(5) + "\n";
waitingList.add(result);
noSMS = rs.getInt(6);
arrayAdapter =
new ArrayAdapter<String>(getApplicationContext(),
android.R.layout.simple_list_item_1,
waitingList) {
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
TextView text = (TextView) view.findViewById(android.R.id.text1);
if (noSMS == 1)
{
text.setTextColor(Color.RED);
}
return view;
}
};
}
lv.setAdapter(arrayAdapter);
}
catch(Exception e)
{
e.printStackTrace();
}
}
There's multiple issues with the code you've provided.
Firstly, when the View is constructed using getView, it's not evaluating the contents of the result string you're passing in as data. Since ResultSet is a transient data container, you'll need a more permanent storage solution for the data you're extracting so it can be evaluated when the ListView needs to update. Create following class:
public class ListItemData {
ListItemData(ResultSet rs) throws SQLException {
name = rs.getString(1);
reservationDate = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.S").parse(rs.getTimestamp(2).toString());
preferredArea = rs.getString(3);
guests = rs.getString(4);
notes = rs.getString(5);
noSms = rs.getInt(6) == 1;
}
String name;
Date reservationDate;
String preferredArea;
String guests;
String notes;
boolean noSms;
}
You're also creating a new ArrayAdapter for each element in the list. This is not how ArrayAdapters are supposed to work! A ListView can have only one ArrayAdapter, and it's logic is run on every item in the list by it's getView method.
The following should be put somewhere outside of loadReservations, probably in onCreate:
// only initialize the waitingList once here, and repopulate it in loadReservations
List<ListItemData> waitingList = new ArrayList<ListItemData>();
// only create the arrayAdapter once
arrayAdapter = new ArrayAdapter<ListItemData>(getApplicationContext(),
android.R.layout.simple_list_item_1,
waitingList) {
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
TextView text = (TextView) view.findViewById(android.R.id.text1);
ListItemData data = getItem(position);
//TODO: now you have access to all the data!
if (data.noSms)
{
text.setTextColor(Color.RED);
}
return view;
}
};
lv.setAdapter(arrayAdapter);
Now that the initialization heavy lifting is done in ListItemData's constructor, our loadReservations function can be greatly simplified:
public void loadReservations() {
ListView lv = (ListView) this.findViewById(R.id.waitingList);
String url = "jdbc:mysql://"+dbURL+":"+dbPort+"/"+dbDatabase+"";
String user = dbUser;
String pass = dbPass;
try {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection(url, user, pass);
Statement st = con.createStatement();
final ResultSet rs = st.executeQuery("SELECT cust_name, reserve_Date, Seat_prefer, reserve_people, Notes, no_sms_service FROM seat_reserve WHERE reserve_Close=0 && DATE(reserve_Date) = DATE(NOW()) ORDER BY reserve_Date ASC");
ResultSetMetaData rsmd = rs.getMetaData();
// clear out the waitingList (instead of making a brand new one!)
waitingList.clear();
while (rs.next()) {
ListItemData data = new ListItemData(rs);
waitingList.add(data);
}
// this must be called to notify the list to recalculate it's view
arrayAdapter.notifyDataSetChanged();
} catch(Exception e) {
e.printStackTrace();
}
}
Keep in mind that I haven't compiled this code, if you spot any issues, let me know and I'll update the answer.