I have a problem with my listview, it works on emulator but not on real device. I tested with 2 real devices and it does not populate. I get listview data from database using json. Json result is ok as it prints to logcat and populates listview on emulator.
ListView Java:
public class ActivityRequestsFrom extends MainActivity implements AdapterView.OnItemClickListener {
______________________________________________________________________________
Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_requests_from);
lv = (ListView) findViewById(R.id.listRequests);
RequestsAdapter adapter = new RequestsAdapter(this, arrRequest_Name, arrRequest_Number,
arrRequest_Username, arrRequest_Result, imageId);
lv.setAdapter(adapter);
lv.setOnItemClickListener(this);
}
______________________________________________________________________________
class RequestsAdapter extends ArrayAdapter<String>
{
Context context;
List<String> Request_Name;
List<String> Request_Number;
List<String> Request_Username;
List<String> Request_Result;
Integer[] imgid;
RequestsAdapter(Context c, List<String> Request_Name,
List<String> Request_Number, List<String> Request_Username,
List<String> Request_Result, Integer[] imgid)
{
super(c, R.layout.activity_requests_single, R.id.textName, Request_Name);
this.context=c;
this.Request_Name=Request_Name;
this.Request_Number=Request_Number;
this.Request_Username=Request_Username;
this.Request_Result=Request_Result;
this.imgid=imgid;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View row=convertView;
if(row==null)
{
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = inflater.inflate(R.layout.activity_requests_single, parent, false); }
TextView txtName = (TextView) row.findViewById(R.id.textName);
TextView txtNumber = (TextView) row.findViewById(R.id.textNumber);
TextView txtUsername = (TextView) row.findViewById(R.id.textUsername);
TextView txtResult = (TextView) row.findViewById(R.id.textResult);
ImageView imageView = (ImageView) row.findViewById(R.id.imageView);
Map<String, Integer> drawableMap = new HashMap<String, Integer>();
drawableMap.put("ok",R.drawable.request_pending_from);
drawableMap.put("pending",R.drawable.request_pending_from);
drawableMap.put("rejected",R.drawable.request_rejected_from);
drawableMap.put("blocked",R.drawable.request_blocked_from);
txtName.setText(Request_Name.get(position));
txtNumber.setText(Request_Number.get(position));
txtUsername.setText(Request_Username.get(position));
txtResult.setText(Request_Result.get(position));
//imageView.setImageResource(imgid[position]);
imageView.setImageResource(drawableMap.get(Request_Result.get(position).toLowerCase()));
return row;
}
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// TODO Auto-generated method stub
TextView tvUsername = (TextView) view.findViewById(R.id.textUsername);
usernameSelected = tvUsername.getText().toString();
TextView tvResult = (TextView) view.findViewById(R.id.textResult);
resultSelected = tvResult.getText().toString();
if (resultSelected.equals("Pending"))
{
pendingOptions();
}
else if (resultSelected.equals("Rejected"))
{
rejectedOptions();
}
else if (resultSelected.equals("Blocked"))
{
blockedOptions();
}
else
{
}
}
ListView Layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ListView
android:id="#+id/listRequest"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
</ListView>
ListView Single Layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/textName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/LLdummy"
android:text="Name"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textStyle="italic"
android:layout_marginLeft="10dp"
/>
<TextView
android:id="#+id/textUsername"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/textNumber"
android:layout_alignParentRight="true"
android:layout_below="#+id/textNumber"
android:text="Username"
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="#+id/textNumber"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/textName"
android:layout_below="#+id/textName"
android:text="Number"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textStyle="bold" />
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="#+id/LLdummy"
android:layout_centerVertical="true"
android:src="#drawable/request_pending_to" />
Json
private class JsonReadTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(params[0]);
try {
HttpResponse response = httpclient.execute(httppost);
jsonResult = inputStreamToString(response.getEntity().getContent()).toString();
}
catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private StringBuilder inputStreamToString(InputStream is) {
String rLine = "";
StringBuilder answer = new StringBuilder();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
try {
while ((rLine = rd.readLine()) != null) {
answer.append(rLine);
}
}
catch (IOException e) {
// e.printStackTrace();
Toast.makeText(getApplicationContext(),"Error..." + e.toString(), Toast.LENGTH_LONG).show();
}
return answer;
}
#Override
protected void onPostExecute(String result) {
try{
ListDrwaer(); //has ConnectionException (when it cannot reach server)
}catch (Exception e){
Toast.makeText(getApplicationContext(), "Please check your connection..", Toast.LENGTH_LONG).show();
}
}
}// end async task
public void accessWebService() {
JsonReadTask task = new JsonReadTask();
// passes values for the urls string array
task.execute(new String[] { "http://server/file.php?pIMEI="+IMEI });
}
// build hash set for list view
public void ListDrwaer() {
try {
JSONObject jsonResponse = new JSONObject(jsonResult);
JSONArray jsonMainNode = jsonResponse.optJSONArray("request_info");
for (int i = 0; i < jsonMainNode.length(); i++) {
JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);
String request_name = jsonChildNode.optString("Request_Name");
String request_number = jsonChildNode.optString("Request_Number");
String request_username = jsonChildNode.optString("Request_Username");
String request_result = jsonChildNode.optString("Request_Result");
arrRequest_Name.add(request_name);
arrRequest_Number.add(request_number);
arrRequest_Username.add(request_username);
arrRequest_Result.add(request_result);
System.out.println("Request_Name: "+request_name);
System.out.println("Request_Number: "+request_number);
System.out.println("Request_Username: "+request_username);
System.out.println("Request_Result: "+request_result);
}
} catch (JSONException e) {
System.out.println("Json Error Requests" +e.toString());
Toast.makeText(getApplicationContext(), "No Requests Pending", Toast.LENGTH_SHORT).show();
}
}
Call Async
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_requests_from);
...
accessWebService();
//ListView
lv = (ListView) findViewById(R.id.listRequests);
RequestsAdapter adapter = new RequestsAdapter(this, arrRequest_Name, arrRequest_Number, arrRequest_Username, arrRequest_Result, imageId);
lv.setAdapter(adapter);
lv.setOnItemClickListener(this);
The problem here is that the data isn't received when the Adapter is set on the ListView. This is because the data is populated in an AysncTask which is async hronous by nature. This means that it will run in the background while the other code runs (i.e. the ListView populating.
So, in onPostExecute() you need to use notifyDataSetChanged() to let the ListView know that there is new items to populate.
#Override
protected void onPostExecute(String result) {
// your code
adapter.notifyDataSetChanged(); // this line here
}// end async task
In your example, this will obviously require you making the Adapter a member variable or passing it to your AsyncTask.
Related
I don't know how to use RecyclerView to replace ListView. Anyone can help me? Thank you. I find out so many resources in the different online platform but I don't know how to change my code. When I trying to alter my code, it doesn't work.
Code is in the following:
MainActivity.java
public class MainActivity extends AppCompatActivity {
private String TAG = MainActivity.class.getSimpleName();
private ProgressDialog pDialog;
private ListView lv;
// URL to get contacts JSON
private static String url = "https://api.androidhive.info/contacts/";
ArrayList<HashMap<String, String>> contactList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
contactList = new ArrayList<>();
lv = (ListView) findViewById(R.id.list);
new GetContacts().execute();
}
/**
* Async task class to get json by making HTTP call
*/
private class GetContacts extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
HttpHandler sh = new HttpHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url);
Log.e(TAG, "Response from url: " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
JSONArray contacts = jsonObj.getJSONArray("contacts");
// looping through All Contacts
for (int i = 0; i < contacts.length(); i++) {
JSONObject c = contacts.getJSONObject(i);
String id = c.getString("id");
String name = c.getString("name");
String email = c.getString("email");
String address = c.getString("address");
String gender = c.getString("gender");
// Phone node is JSON Object
JSONObject phone = c.getJSONObject("phone");
String mobile = phone.getString("mobile");
String home = phone.getString("home");
String office = phone.getString("office");
// tmp hash map for single contact
HashMap<String, String> contact = new HashMap<>();
// adding each child node to HashMap key => value
contact.put("id", id);
contact.put("name", name);
contact.put("email", email);
contact.put("mobile", mobile);
// adding contact to contact list
contactList.add(contact);
}
} catch (final JSONException e) {
Log.e(TAG, "Json parsing error: " + e.getMessage());
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
"Json parsing error: " + e.getMessage(),
Toast.LENGTH_LONG)
.show();
}
});
}
} else {
Log.e(TAG, "Couldn't get json from server.");
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
"Couldn't get json from server. Check LogCat for possible errors!",
Toast.LENGTH_LONG)
.show();
}
});
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
ListAdapter adapter = new SimpleAdapter(
MainActivity.this, contactList,
R.layout.list_item, new String[]{"name", "email",
"mobile"}, new int[]{R.id.name,
R.id.email, R.id.mobile});
lv.setAdapter(adapter);
}
}
}
HttpHandler.java
public class HttpHandler {
private static final String TAG = HttpHandler.class.getSimpleName();
public HttpHandler() {
}
public String makeServiceCall(String reqUrl) {
String response = null;
try {
URL url = new URL(reqUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
// read the response
InputStream in = new BufferedInputStream(conn.getInputStream());
response = convertStreamToString(in);
} catch (MalformedURLException e) {
Log.e(TAG, "MalformedURLException: " + e.getMessage());
} catch (ProtocolException e) {
Log.e(TAG, "ProtocolException: " + e.getMessage());
} catch (IOException e) {
Log.e(TAG, "IOException: " + e.getMessage());
} catch (Exception e) {
Log.e(TAG, "Exception: " + e.getMessage());
}
return response;
}
private String convertStreamToString(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line;
try {
while ((line = reader.readLine()) != null) {
sb.append(line).append('\n');
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="hk.edu.ouhk.android.jsonparsing.MainActivity">
<ListView
android:id="#+id/list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
list_item.xml
<?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="wrap_content"
android:orientation="vertical"
android:padding="16dip">
<TextView
android:id="#+id/name"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingBottom="2dip"
android:paddingTop="6dip"
android:textColor="#color/colorPrimaryDark"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="#+id/email"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingBottom="2dip"
android:textColor="#5d5d5d" />
<TextView
android:id="#+id/mobile"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#686868"
android:textStyle="bold" />
</LinearLayout>
as you seems to have no problem getting data from url and you successfully have made an Arraylist from the data
steps to follow now
1. add recyclerview to xml of your activity
2. make a layout how you want to display data in recyclerview items
3. then you need to make an adapter that takes data you provide and binds it to
recycler view
4. then add adapter to your recycler view
I am attaching simple recycler view which I made a while ago for me. It is simple and self explanatory. Otherwise you can comment I will explain it more
Main Activity
public class MainActivity extends AppCompatActivity {
ArrayList<String> moviesList;
RecyclerView recyclerView;
RecyclerAdapter recyclerAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
moviesList=new ArrayList<>();
recyclerView=findViewById(R.id.recyclerView);
recyclerAdapter=new RecyclerAdapter(moviesList);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(recyclerAdapter);
moviesList.add("Kapil");
moviesList.add("Kapil");
moviesList.add("Kapil");
moviesList.add("Kapil");
moviesList.add("Kapil");
moviesList.add("Kapil");
moviesList.add("Kapil"); }
}
RecyclerAdapter in this we are creating custom viewholder for us
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder>
{
public RecyclerAdapter(ArrayList<String> moviesList) {
this.moviesList = moviesList;
}
ArrayList<String> moviesList;
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater=LayoutInflater.from(parent.getContext());
View view=layoutInflater.inflate(R.layout.row_layout,parent,false);
ViewHolder viewHolder= new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
holder.rowTextView.setText(String.valueOf(position));
holder.textView.setText(moviesList.get(position));
}
#Override
public int getItemCount() {
return moviesList.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
TextView textView,rowTextView;
public ViewHolder(#NonNull View itemView) {
super(itemView);
imageView=itemView.findViewById(R.id.imageView);
textView=itemView.findViewById(R.id.textView);
rowTextView=itemView.findViewById(R.id.rowTextView);
}
}
}
This is layout for the item which I want to show in recycler view
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="22dp"
android:layout_marginTop="16dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/ic_launcher_background" />
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="22dp"
android:text="TextView"
android:textAppearance="#style/TextAppearance.AppCompat.Large"
app:layout_constraintStart_toEndOf="#+id/imageView"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/rowTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="33dp"
android:layout_marginTop="16dp"
android:text="TextView"
app:layout_constraintStart_toEndOf="#+id/imageView"
app:layout_constraintTop_toBottomOf="#+id/textView" />
</androidx.constraintlayout.widget.ConstraintLayout>
Just pass your array list to it. Like i did
Basically you need to create RecyclerViewAdapter with ViewHolder pattern, and just simply replace ListView to RecyclerView
i have json which contains image url and
i follow this tutorial ,i download source code,works fine, but when i implement same thing in my application it displays my listview is empty
when i'm debug the code i getting know ,the adapter which has to fill the list view is load the data ,but listview cant
this is my activity
public class ListNotificationActivity extends AppCompatActivity {
Toolbar toolbar;
private ProgressDialog pDialog;
private static String url = "http://staging.talentslist.com/api/user/24/notification";
ArrayList<NotificationData> notiList;
ListView listview;
NotificAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_notification);
toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle(getResources().getString(R.string.notification));
setSupportActionBar(toolbar);
notiList = new ArrayList<NotificationData>();
new GetList().execute(url);
listview = (ListView) findViewById(R.id.notificationList);
adapter = new NotificAdapter(getApplicationContext(), R.layout.list_item, notiList);
listview.setAdapter(adapter);
}
private class GetList extends AsyncTask<String, Void, Boolean> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(ListNotificationActivity.this);
pDialog.setMessage("Loading, please wait");
pDialog.setTitle("Connecting server");
pDialog.show();
pDialog.setCancelable(false);
}
#Override
protected Boolean doInBackground(String... urls) {
HttpGet httppost = new HttpGet(urls[0]);
URL urlObj = null;
try {
urlObj = new URL(urls[0]);
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = httpclient.execute(httppost);
HttpURLConnection urlConnection = (HttpURLConnection) urlObj.openConnection();
InputStream is = urlConnection.getInputStream();
// StatusLine stat = response.getStatusLine();
int status = response.getStatusLine().getStatusCode();
// int status = urlConnection.getResponseCode();
if (status == 200) {
HttpEntity entity = response.getEntity();
String data = EntityUtils.toString(entity);
JSONObject jsono = new JSONObject(data);
JSONArray jarray = jsono.getJSONArray("data");
for (int i = 0; i < jarray.length(); i++) {
JSONObject object = jarray.getJSONObject(i);
NotificationData notidata = new NotificationData();
notidata.setId(object.getInt("id"));
notidata.setUser_name(object.getString("user_name"));
notidata.setTitle(object.getString("title"));
notidata.setIs_read(object.getString("is_read"));
notidata.setCreated_at(object.getString("created_at"));
notidata.setImage_link(object.getString("image_link"));
notiList.add(notidata);
}
return true;
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return false;
}
protected void onPostExecute(Boolean result) {
pDialog.cancel();
adapter.notifyDataSetChanged();
if (result == false)
Toast.makeText(getApplicationContext(), "Unable to fetch data from server", Toast.LENGTH_LONG).show();
}
}
}
this is my adapter class
public class NotificAdapter extends ArrayAdapter<NotificationData> {
ArrayList<NotificationData> nDataAdapter;
LayoutInflater vi;
int Resource;
ViewHolder holder;
public NotificAdapter(Context context, int resource, ArrayList<NotificationData> objects) {
super(context, resource);
vi = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
Resource = resource;
nDataAdapter = objects;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
holder = new ViewHolder();
v = vi.inflate(Resource, null);
holder.imageview = (ImageView) v.findViewById(R.id.list_image);
holder.tvSender_name = (TextView) v.findViewById(R.id.sender_name);
holder.tvNoti_details = (TextView) v.findViewById(R.id.noti_details);
holder.tvDate = (TextView) v.findViewById(R.id.date);
v.setTag(holder);
} else {
holder = (ViewHolder) v.getTag();
}
holder.imageview.setImageResource(R.drawable.noimage);
new DownloadImageTask(holder.imageview).execute(nDataAdapter.get(position).getImage_link());
holder.tvSender_name.setText(nDataAdapter.get(position).getUser_name());
holder.tvNoti_details.setText(nDataAdapter.get(position).getUser_name());
holder.tvDate.setText(nDataAdapter.get(position).getCreated_at());
return v;
}
private class ViewHolder {
public ImageView imageview;
public TextView tvSender_name;
public TextView tvNoti_details;
public TextView tvDate;
}
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
public DownloadImageTask(ImageView bmImage) {
this.bmImage = bmImage;
}
#Override
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
}
this is list item layout for listview
<?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:background="#drawable/list_selector"
android:orientation="horizontal"
android:padding="5dip" >
<!-- ListRow Left sied Thumbnail image -->
<LinearLayout
android:id="#+id/thumbnail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginRight="5dip"
android:background="#drawable/image_bg"
android:orientation="vertical"
android:padding="3dip">
<ImageView
android:id="#+id/list_image"
android:layout_width="50dip"
android:layout_height="50dip"
android:src="#drawable/noimage" />
</LinearLayout>
<TextView
android:id="#+id/sender_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/thumbnail"
android:layout_toRightOf="#+id/thumbnail"
android:text="Notification from"
android:textColor="#040404"
android:typeface="sans"
android:textSize="15dip"
android:textStyle="bold"/>
<TextView
android:id="#+id/noti_details"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="#+id/thumbnail"
android:text="Notification details"
android:textColor="#343434"
android:textSize="10dip" />
<TextView
android:id="#+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignTop="#id/name"
android:gravity="right"
android:text="Time"
android:layout_marginRight="5dip"
android:textSize="10dip"
android:textColor="#10bcc9"
android:textStyle="bold"/>
</RelativeLayout>
please help me!!
make some changes when you getting data to add all data into list.
and make separate method for set adapter like below ..
/**
* this method used set adapter into list view.
*/
private void setAdapter(){
if (adapter==null) {
adapter = new NotificAdapter(getApplicationContext(), R.layout.list_item, notiList);
listview.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
else{
adapter.notifyDataSetChanged();
}
}
then after above method call in this block in your code ..
protected void onPostExecute(Boolean result) {
setAdapter();
if (result == false)
Toast.makeText(getApplicationContext(), "Unable to fetch data from server", Toast.LENGTH_LONG).show();
}
I am doing some troubleshooting on my code, I have noticed that sometimes the listview row is returned multiple times when I post new data instead of once. I am reading contents of the listview row from database and projecting it into the else if statement of getView (commented out the Bitmap to test with textview, still having same problem)
getView:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View row=convertView;
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (request_my_username.equals(arrRequest_UserContact.get(position))) //YOU
{
if (Request_Message.get(position).equals("MESSAGE-FAILED-TO-POST"))
{
row = inflater.inflate(R.layout.activity_chatprivate_single_right, parent, false);
TextView txtMessage = (TextView) row.findViewById(R.id.textMessage);
txtMessage.setTypeface(null, Typeface.BOLD);
txtMessage.setText(Request_Message.get(position));
}
else if (Request_Message.get(position).contains("/storage/"))
{
/***
row = inflater.inflate(R.layout.activity_chatprivate_single_right_img, parent, false);
Bitmap bmp_ico = BitmapFactory.decodeFile(Request_Message.get(position));
ImageButton ib = (ImageButton) row.findViewById(R.id.ib);
ib.setImageBitmap(bmp_ico);
***/
row = inflater.inflate(R.layout.activity_chatprivate_single_right, parent, false);
TextView txtMessage = (TextView) row.findViewById(R.id.textMessage);
txtMessage.setText(Request_Message.get(position));
}
else
{
row = inflater.inflate(R.layout.activity_chatprivate_single_right, parent, false);
TextView txtMessage = (TextView) row.findViewById(R.id.textMessage);
txtMessage.setText(Request_Message.get(position));
}
}
Read MySQL:
private class JsonReadChatPrivate extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(params[0]);
try {
HttpResponse response = httpclient.execute(httppost);
jsonResult = inputStreamToString(response.getEntity().getContent()).toString();
}
catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private StringBuilder inputStreamToString(InputStream is) {
String rLine = "";
StringBuilder answer = new StringBuilder();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
try {
while ((rLine = rd.readLine()) != null) {
answer.append(rLine);
}
}
catch (IOException e) {
}
return answer;
}
#Override
protected void onPostExecute(String result) {
adapter.notifyDataSetChanged();
try{
ListDrawer_readPrivateChat(); //has ConnectionException (when it cannot reach server)
}catch (Exception e){
}
}
}
public void accessWebService_readChatPrivate() {
JsonReadChatPrivate task = new JsonReadChatPrivate();
task.execute(new String[] { "http://website/php/file_to_read_db.php?pcontactSelected="+contactSelected+"&pIMEI="+IMEI+"&pmysql_room_id="+mysql_room_id});
}
public void ListDrawer_readPrivateChat() {
try {
JSONObject jsonResponse = new JSONObject(jsonResult);
JSONArray jsonMainNode = jsonResponse.optJSONArray("request_chat_private");
for (int i = 0; i < jsonMainNode.length(); i++) {
JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);
String request_message = jsonChildNode.optString("Message");
String request_time = jsonChildNode.optString("Time");
mysql_room_id = jsonChildNode.optString("_id");
request_last_user = jsonChildNode.optString("LastUser");
arrRequest_UserContact.add(request_last_user);
arrRequest_Message.add(request_message);
arrRequest_Time.add(request_time);
adapter.notifyDataSetChanged();
}
} catch (JSONException e) {
}
}
Listening every 5 seconds to see if there is any new data on MySQL and if there is, return only the contents from the last MySQL ID (so that I do not re-add items that exist onto the listview):
private void DBListern() {
accessWebService_readChatPrivate();
}
private void loop() {
handler.postDelayed(new Runnable() {
public void run() {
DBListern();
handler.postDelayed(this, 5000);
}
}, 5000);
}
XML:
<?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"
android:background="#drawable/bg_chat_2"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_weight="1"
>
<ListView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:transcriptMode="normal"
android:stackFromBottom="true"
android:divider="#null"
android:dividerHeight="0dp"
>
</ListView>
</LinearLayout>
...
With above said, when I post content as A then B then C it should return the correct output as A, B, C however it does this A, AA, BBB, CCCC <-- repeating the view with same data.
OK, I continued troubleshooting with logs and toasts, the problem was not the getView, it was actually the selecting of image from gallery, when doing so it calls onPauce() and after selecting an image it then calls onResume which runs the loop() call again while it as already running. All I did was cancel the previous loop (handler.removeCallbacksAndMessages(null);) as it will be called again with onResume
I admit my focus was more on the getView code of the listView, I never thought selecting an image calls system methods. Always good to work with logs.
I am trying to populate the result onto a listview once I press the search button. But, when i try to do it, nothing is displayed on the listview.
I am using asynctask to get the data from database and pass it into the listview as a array.
Thanks for the help in advance!
Below are the code:
public class FindFriends extends Activity implements View.OnClickListener {
EditText handphone;
Button searchbtn;
String name,hp;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.findfriends);
handphone = (EditText) findViewById(R.id.enterfn);
searchbtn = (Button) findViewById(R.id.searchfor);
searchbtn.setOnClickListener(this);
ListView listview = (ListView) findViewById(R.id.listView);
String[] values = new String[]{name};
ArrayAdapter<String> codeLearnArrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, values);
listview.setAdapter(codeLearnArrayAdapter);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.searchfor:
hp = handphone.getText().toString();
new AttemptLogin().execute(hp);
break;
}
}
class AttemptLogin extends AsyncTask<String, String, JSONObject> {
private ProgressDialog pDialog;
// JSON parser class
JSONParser jsonParser = new JSONParser();
private static final String LOGIN_URL = "address_url";
#Override
protected JSONObject doInBackground(String... args) {
// TODO Auto-generated method stub
// here Check for success tag
try {
HashMap<String, String> params = new HashMap<>();
params.put("hp", args[0]);
JSONObject json = jsonParser.makeHttpRequest(
LOGIN_URL, "POST", params);
if (json != null) {
Log.d("JSON result", json.toString());
return json;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(JSONObject json) {
if (json != null) {
Toast.makeText(FindFriends.this, json.toString(),
Toast.LENGTH_LONG).show();
try {
name = json.getString("name");
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
findfriends.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:background="#drawable/findfriends"
android:layout_height="match_parent">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:ems="10"
android:id="#+id/enterfn"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Enter handphone number/username to start searching"
android:id="#+id/textView9"
android:textSize="20dp"
android:layout_above="#+id/enterfn"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Search"
android:id="#+id/searchfor"
android:layout_below="#+id/enterfn"
android:layout_centerHorizontal="true" />
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/listView"
android:layout_below="#+id/searchfor"
android:layout_centerHorizontal="true" />
</RelativeLayout>
I'm new in Android.
Anyway I can't see where you update your array, in the AsyncTask you download the data but you don't update values. So you shuld update the array passed to the adapter and then call the it's method notifyDataSetChanged()
Just go through the below code and replcae it with your,
public class FindFriends extends Activity implements View.OnClickListener {
EditText handphone;
Button searchbtn;
String name = "name", hp = "hp";
ListView listview;
ArrayAdapter<String> codeLearnArrayAdapter;
ArrayList<String> values;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.findfriends);
handphone = (EditText) findViewById(R.id.enterfn);
searchbtn = (Button) findViewById(R.id.searchfor);
searchbtn.setOnClickListener(this);
listview = (ListView) findViewById(R.id.listView);
// adding value to arrayList
values.add(name);
codeLearnArrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, values);
listview.setAdapter(codeLearnArrayAdapter);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.searchfor:
hp = handphone.getText().toString();
new AttemptLogin(new MyHandler()).execute(hp);
break;
}
}
class AttemptLogin extends AsyncTask<String, String, JSONObject> {
private ProgressDialog pDialog;
// JSON parser class
JSONParser jsonParser = new JSONParser();
private static final String LOGIN_URL = "address_url";
MyHandler myHandler;
public AttemptLogin(MyHandler myHandler) {
this.myHandler = myHandler;
}
#Override
protected JSONObject doInBackground(String... args) {
// TODO Auto-generated method stub
// here Check for success tag
try {
HashMap<String, String> params = new HashMap<>();
params.put("hp", args[0]);
JSONObject json = jsonParser.makeHttpRequest(
LOGIN_URL, "POST", params);
if (json != null) {
Log.d("JSON result", json.toString());
return json;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(JSONObject json) {
if (json != null) {
Toast.makeText(FindFriends.this, json.toString(),
Toast.LENGTH_LONG).show();
try {
name = json.getString("name");
Message message = new Message();
message.obj = name;
myHandler.sendMessage(message);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
private class MyHandler extends Handler {
#Override
public void handleMessage(Message msg) {
String response = String.valueOf(msg);
values.add(response);
codeLearnArrayAdapter.notifyDataSetChanged();
}
}
}
And let me know if it works...
you missed adapter.notifyDataSetChanged();
Use this method after data changing
UPD
try this code:
protected void onPostExecute(JSONObject json) {
if (json != null) {
Toast.makeText(FindFriends.this, json.toString(),
Toast.LENGTH_LONG).show();
try {
name = json.getString("name");
values[0]=name;
codeLearnArrayAdapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
}
Hope it works. Otherwise let me know about it.
P.S. You should also use List instead of array.
I am trying to parse the data into the list View in android
JSON:: http://54.218.73.244:7000/
It has a JSON output :: [{"restaurantID":1,"restaurantNAME":"CopperChimney"},{"restaurantID":2,"restaurantNAME":"Aroy"},{"restaurantID":3,"restaurantNAME":"MarkBoulevard"}]
I am trying to display the CopperChimney, Aroy, MarkBoulevard in a
list view
I figured some small parts but can someone help me fill
AndroidJSONParsingActivity.java part of the code which invoolves putting data in a collection and displaying it
Any ideas ?
JSONParser
public class JSONParser {
static InputStream is = null;
static JSONArray jObj = null;
static String json = "";
// constructor
public JSONParser() {
}
public JSONArray getJSONFromUrl(String url) {
// Making HTTP request
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
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();
json = sb.toString();
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// try parse the string to a JSON object
try {
jObj = new JSONArray(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
// return JSON String
return jObj;
}
}
Item.java
public class Item{
private String Name;
public Item(String name){
this.Name = name;
}
public String getName(){
return Name;
}
}
ListAdapter.java
public class ListAdapter extends ArrayAdapter<Item> {
private List<Item> items;
public ListAdapter(Context context, int resource, List<Item> items) {
super(context, resource, items);
this.items = items;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
TextView tt = null;
if (v == null) {
LayoutInflater vi;
vi = LayoutInflater.from(getContext());
v = vi.inflate(R.layout.itemlistrow, null);
tt = (TextView) v.findViewById(R.id.RestaurantNameID);
}
Item p = items.get(position);
if (p != null) {
if (tt != null) {
tt.setText(""+p.getName());
}
}
return v;
}
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ListView
android:id="#+id/listViewID"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center">
</ListView>
</LinearLayout>
itemlistrow.xml
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content" android:orientation="vertical"
android:layout_width="fill_parent">
<TableRow android:layout_width="fill_parent"
android:id="#+id/TableRow01"
android:layout_height="wrap_content">
<TextView
android:id="#+id/RestaurantNameID"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="name" android:textStyle="bold"
android:gravity="left"
android:layout_weight="1"
android:typeface="monospace"
android:height="40sp"/>
</TableRow>
</TableLayout>
AndroidJSONParsingActivity.java
public class AndroidJSONParsingActivity extends Activity {
private static String url = "http://54.218.73.244:7000/";
//
//
//
//
/------ CODE -Trying to ADD ------ /
//
//
}
CODE I TRIED FOR AndroidJSONParsingActivity.java
public class AndroidJSONParsingActivity extends Activity {
// url to make request
private static String url = "http://54.218.73.244:7000/";
List<Item> yourData = new ArrayList<Item>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Creating JSON Parser instance
JSONParser jParser = new JSONParser();
// getting JSON string from URL
JSONArray json = jParser.getJSONFromUrl(url);
try {
for (int i = 0; i < json.length(); i++) {
JSONObject c = json.getJSONObject(i);
// Storing each json item in variable
String NAME=c.getString("restaurantNAME");
yourData.add(new Item(NAME));
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ListView yourListView = (ListView) findViewById(R.id.listViewID);
ListAdapter customAdapter = new ListAdapter(this, R.layout.itemlistrow, yourData);
yourListView.setAdapter(customAdapter);
yourListView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// When clicked, show a toast with the TextView text
if(position == 0)
{
//code specific to first list item
Intent myIntent = new Intent(AndroidJSONParsingActivity.this,Employee1.class);
startActivity(myIntent);
}else if(position == 1)
{
Intent myIntent = new Intent(AndroidJSONParsingActivity.this,Employee2.class);
startActivity(myIntent);
}
}
});
}
}
public class AndroidJSONParsingActivity extends ListActivity {
ArrayList <Item> list = new ArraList <Item>();
#Override
public void onStart() {
super.onStart();
new GetHttpData().execute();
}
private class GetHttpData extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
private static String url = "http://54.218.73.244:7000/";
JSONArray jArray = getJSONFromUrl(url);
int len = jArray.length();
for(int i = 0; i < len; i++) {
JSONObject restaurant = jArray.getJSONObject(i);
list.add(new Item(restaurant.getString("restaurantNAME"));
}
return null;
}
#Override
protected void onPostExecute(Void result) {
setListAdapter(new ListAdapter(AndroidJSONParsingActivity.this, android.R.layout.simple_list_item_1, list));
}
}
}
This is just one way to parse it, you should also do all HttpRequests and JSON parsing in a separate thread, see http://developer.android.com/reference/android/os/AsyncTask.html
Edited:
You can also check this Example