Data varying in GridView in Android App - android

I am developing an Android app which displays information of different historical places. In my App, I have made a page to review and rate the place. The app is retrieving usernames, ratings, and comments from database and displaying it in a GridView. It is displaying correct number of comments but instead of displaying all the comments it duplicates some of the comments. Here is my code which retrieve data from database.
Can anyone tell what is the problem with my code??
class task extends AsyncTask<String, String, Void>
{
private ProgressDialog progressDialog = new ProgressDialog(Comments.this);
InputStream is = null ;
String result = "";
protected void onPreExecute()
{
if (get)
progressDialog.setMessage("Retrieving reviews...");
else
progressDialog.setMessage("Posting review...");
progressDialog.show();
progressDialog.setOnCancelListener(new OnCancelListener()
{
#Override
public void onCancel(DialogInterface arg0)
{
task.this.cancel(true);
}
});
}
#Override
protected Void doInBackground(String... params)
{
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url_select);
try
{
httpPost.setEntity(new UrlEncodedFormEntity(param));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
//read content
is = httpEntity.getContent();
}
catch (Exception e)
{
Log.e("log_tag", "Error in http connection "+e.toString());
}
try
{
BufferedReader br = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = "";
while((line=br.readLine())!=null)
{
sb.append(line+"\n");
}
is.close();
result=sb.toString();
}
catch (Exception e)
{
// TODO: handle exception
Log.e("log_tag", "Error converting result "+e.toString());
}
return null;
}
protected void onPostExecute(Void v)
{
try
{
if(get)
{
name=new ArrayList<String>();
comment=new ArrayList<String>();
rating=new ArrayList<Float>();
JSONArray Jarray = new JSONArray(result);
for(int i=0;i<Jarray.length();i++)
{
JSONObject Jasonobject = new JSONObject();
Jasonobject = Jarray.getJSONObject(i);
String names=null;
names=Jasonobject.getString("name");
name.add(names);
comment.add(Jasonobject.getString("comment"));
rating.add((float)Jasonobject.getDouble("rating"));
}
CustomGrid adapter = new CustomGrid(Comments.this, name,comment,rating);
grid.setAdapter(adapter);
get=false;
}
progressDialog.dismiss();
}
catch (Exception e)
{
// TODO: handle exception
Log.e("log_tag", "Error parsing data "+e.toString());
}
}
}
Adapter Code:
public class CustomGrid extends BaseAdapter
{
private Context mContext;
private final ArrayList<String> name;
private final ArrayList<String> comment;
private final ArrayList<Float> rating;
public CustomGrid(Context c,ArrayList<String> name, ArrayList<String> comment, ArrayList<Float> rating )
{
mContext = c;
this.name= name;
this.comment = comment;
this.rating=rating;
}
#Override
public int getCount()
{
// TODO Auto-generated method stub
return comment.size();
}
#Override
public Object getItem(int position)
{
// TODO Auto-generated method stub
return null;
}
#Override
public long getItemId(int position)
{
// TODO Auto-generated method stub
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
// TODO Auto-generated method stub
View grid;
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null)
{
grid = new View(mContext);
grid = inflater.inflate(R.layout.grid, null);
TextView textName = (TextView) grid.findViewById(R.id.grid_name);
TextView textComment = (TextView) grid.findViewById(R.id.grid_comment);
RatingBar ratingBar1 = (RatingBar)grid.findViewById(R.id.grid_rating);
textName.setText(name.get(position));
textComment.setText(comment.get(position));
ratingBar1.setRating(rating.get(position));
}
else
{
grid = (View) convertView;
}
return grid;
}
}

convertView is null just once. After you inflate and return it, due to the recycling mechanism of the GridView/ListView it will be never null again. What you are doing is assign to your TextViews the content of your dataset at position 0, and then return on of the pooled view with the same content over and over. Change your getView like:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.grid, null);
}
TextView textName = (TextView) convertView.findViewById(R.id.grid_name);
TextView textComment = (TextView) convertView.findViewById(R.id.grid_comment);
RatingBar ratingBar1 = (RatingBar)convertView.findViewById(R.id.grid_rating);
textName.setText(name.get(position));
textComment.setText(comment.get(position));
ratingBar1.setRating(rating.get(position));
return convertView;
}
also you probably want to look in the ViewHolder pattern, which makes your GridView/ListView scroll smoother

Related

onResume Does Not Update ListView With New Data

I am trying to update a ListView on previous fragment after back button press. The onResume is called (verified with Toast) and the webservice runs (listView is displayed after it is cleared). The problem is that the ListView is still showing old values and not new value after accessWebService_getUsername is called. I verify the values from MySQL and even though the DB is updated, the ListView only returns old values.
#Override
public void onResume() {
Toast.makeText(getActivity(), "onResume", Toast.LENGTH_SHORT).show();
super.onResume();
adapter.clear();
getIMEI();
accessWebService_getUsername();
adapter.notifyDataSetChanged();
}
Update:
//ListView
ListView lv =(ListView)view.findViewById(R.id.listView);
adapter = new ContactsAdapter(getActivity(), arrRequest_Contact, arrRequest_NameSurname, arrRequest_MessageCount, arrRequest_Time, arrRequest_Image);
lv.setAdapter(adapter);
// Json
private class JsonGetUsername extends AsyncTask<String, Void, String> {
//Pending 01
private ProgressDialog dialog = new ProgressDialog(getActivity());
#Override
protected void onPreExecute() {
this.dialog.setMessage("Loading Contacts, Please Wait");
this.dialog.show();
}
#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(getActivity(),"Error..." + e.toString(), Toast.LENGTH_LONG).show();
}
return answer;
}
#Override
protected void onPostExecute(String result) {
//Pending 02
if (dialog.isShowing()) {
dialog.dismiss();
}
adapter.notifyDataSetChanged();
try{
ListDrawer_getUsername(); //has ConnectionException (when it cannot reach server)
}catch (Exception e){
Toast.makeText(getActivity(), "Please check your connection..", Toast.LENGTH_LONG).show();
}
}
}// end async task
public void accessWebService_getUsername() {
JsonGetUsername task = new JsonGetUsername();
// passes values for the urls string array
task.execute(new String[] { "http://mywebsite/php/get_username.php?pIMEI="+IMEI});
}
// build hash set for list view
public void ListDrawer_getUsername() {
try {
JSONObject jsonResponse = new JSONObject(jsonResult);
JSONArray jsonMainNode = jsonResponse.optJSONArray("username_info");
for (int i = 0; i < jsonMainNode.length(); i++) {
JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);
request_username = jsonChildNode.optString("Username");
}
accessWebService_getContacts();
} catch (JSONException e) {
System.out.println("Json Error Rooms" +e.toString());
//Toast.makeText(getApplicationContext(), "No Rooms To Load", Toast.LENGTH_SHORT).show();
}
}
UPDATE 2:
//ContactsAdpater
class ContactsAdapter extends ArrayAdapter<String>
{
Context context;
List<String> Request_Contact;
List<String> Request_NameSurname;
List<String> Request_MessageCount;
List<String> Request_Time;
List<String> Request_Image;
ContactsAdapter(Context c, List<String> Request_Contact, List<String> Request_NameSurname, List<String> Request_MessageCount, List<String> Request_Time, List<String> Request_Image)
{
super(c, R.layout.activity_contacts_single, R.id.textContact, Request_Contact);
this.context=c;
this.Request_Contact=Request_Contact;
this.Request_NameSurname=Request_NameSurname;
this.Request_MessageCount=Request_MessageCount;
this.Request_Time=Request_Time;
this.Request_Image=Request_Image;
}
#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_contacts_single, parent, false);
}
TextView txtContact = (TextView) row.findViewById(R.id.textContact);
TextView txtNameSurname = (TextView) row.findViewById(R.id.textNameSurname);
TextView txtMessageCount = (TextView) row.findViewById(R.id.textMessageCount);
TextView txtTime = (TextView) row.findViewById(R.id.textTime);
ImageView imageView = (ImageView) row.findViewById(R.id.imageView);
txtContact.setText(Request_Contact.get(position));
txtNameSurname.setText(Request_NameSurname.get(position));
txtMessageCount.setText(Request_MessageCount.get(position));
txtTime.setText(Request_Time.get(position));
Picasso.with(context).load(arrRequest_Image.get(position)).transform(new CircleTransform()).placeholder(R.drawable.ic_launcher).into(imageView);
return row;
}
}
You'll need to override the clear method in your ContactsAdapter to actually clear the lists you are storing your data in.
It looks like you'll need to clear all your lists, so if you add this to ContactsAdapter, your code should work as expected:
#Override
public void clear() {
super.clear();
Request_Contact.clear();
Request_NameSurname.clear();
Request_MessageCount.clear();
Request_Time.clear();
Request_Image.clear();
}

Limiting ListView with AsyncTask Using ArrayAdapter

I am developing app just like YOUTUBE. I am getting data from the server and showing it in listview. Because data is too big so i want to restrict list view to 5 items and then when I scroll down to the bottom of listview it should add 5 more item.
I am calling ASyncTask from fragment
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
LayoutInflater layoutInflater = LayoutInflater.from(getContext());
view = layoutInflater.inflate(R.layout.tab_fragment_2, container, false);
listView = (ListView) view.findViewById(R.id.myList);
New.jsonAsyncTask.execute("my url select_video.php?");
}
Now I have separate JsonAsyncTask Class because I am calling it from 3 fragments just like above mentioned way..
public class JSONAsyncTask extends AsyncTask<String, String, List<SetDatails>> {
ListView listView1;
Context context1;
List<SetDatails> videoLiast1;
private static int tab_id;
public JSONAsyncTask(ListView listView, List<SetDatails> videoLiast,Context context,int id) {
this.listView1 = listView;
this.context1 = context;
this.videoLiast1 = videoLiast;
tab_id=id;
}
#Override
protected List<SetDatails> doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader myReader = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream myInputStream = connection.getInputStream();
myReader = new BufferedReader(new InputStreamReader(myInputStream));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = myReader.readLine()) != null) {
buffer.append(line);
}
String Json_data = buffer.toString();
videoLiast1 = new ArrayList<>();
JSONObject parentObj = new JSONObject(Json_data);
JSONArray dataArray = parentObj.getJSONArray("data");
JSONObject tabObject = dataArray.getJSONObject(tab_id);
JSONArray videoArray = tabObject.getJSONArray("videos");
for (int i = 0; i < videoArray.length(); i++) {
int len=dataArray.length();
SetDatails setDatails = new SetDatails();
JSONObject arrayChild = videoArray.getJSONObject(i);
String vid_ID = arrayChild.getString("id");
setDatails.setVidID(vid_ID);
String movie_title = arrayChild.getString("name");
setDatails.setTitle(movie_title);
String movie_catagory = arrayChild.getString("category_name");
setDatails.setGenre(movie_catagory);
videoLiast1.add(setDatails);
}
return videoLiast1;
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} catch (Throwable throwable) {
throwable.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
try {
if (myReader != null) {
myReader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
protected void onPostExecute(List<SetDatails> videoList) {
super.onPostExecute(videoList);
if(videoList!=null) {
try {
MyListAdapter myListAdapter = new MyListAdapter(context1, videoList);
listView1.setAdapter(myListAdapter);
}catch (Exception ex)
{
ex.printStackTrace();
}
}
}
}
I have created an Array adapter to fill list view.
public class MyListAdapter extends ArrayAdapter<SetDatails>{
public static int count =5;
List<SetDatails> videoList;
MyListAdapter(Context context,List<SetDatails> object){
super(context,R.layout.tab2_bookchilds,object);
videoList = object;
}
/**
* {#inheritDoc}
*/
#Override
public int getCount() {
return super.getCount();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater layoutInflater=LayoutInflater.from(getContext());
View view = layoutInflater.inflate(R.layout.tab2_bookchilds, parent, false);
TextView title = (TextView)view.findViewById(R.id.txt_title);
title.setText(videoList.get(position).getTitle());
ImageView imgV_Thumbnail = (ImageView) view.findViewById(R.id.imgV_thumbnail);
Picasso.with(getContext())
.load(videoList.get(position).getThumbnail())
.error(R.drawable.icon_white)
.into(imgV_Thumbnail);
return view;
}
}
I have searched a lot and many people suggest getCount() method although I tried a lot to use this method but don't know how to do that.
Please guys help me because my app is ready to upload but I can't solve this one issue.

Call BaseAdapter In Fragment Close Application

Call BaseAdapter In Fragment Close Application
Comment in line spinner.setAdapter(new Category_Adapter(getActivity(), categorylist));
Work
Error Log
Class FragmentNews
public class FragmentNews extends Fragment {
ArrayList<Category> categorylist = new ArrayList<Category>();
#Override
public View onCreateView(final LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
// TODO Auto-generated method stub
final View rootView = inflater.inflate(R.layout.fragment_news,
container, false);
Spinner spinner = (Spinner) rootView.findViewById(R.id.category);
new fechPosts().execute("");
return rootView;
}
class fechPosts extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
ringProgressDialog = new ProgressDialog(getActivity());
ringProgressDialog.setMessage("در حال ارسال پیام");
ringProgressDialog.setCancelable(true);
ringProgressDialog.show();
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
String result = fetch(params[0]);
return result;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Activity myActivity = getActivity();
spinner.setAdapter(new Category_Adapter(getActivity(), categorylist));
ringProgressDialog.dismiss();
}
}
public String fetch(String titel) {
// Create a new HttpClient and Post Header
HttpClient httpclient = new DefaultHttpClient();
HttpGet httppost = null;
httppost = new HttpGet(
"http://mynikan.ir/paliz/mobile/GetAllProduct.php");
String r = "ok";
String result = null;
InputStream inputStream = null;
try {
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
inputStream = response.getEntity().getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(
inputStream, "iso-8859-1"));
StringBuilder sb = new StringBuilder();
sb.append(reader.readLine() + "\n");
String line = "";
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
result = sb.toString();
JSONArray array = null;
try {
array = new JSONArray(result);
} catch (JSONException e) {
e.printStackTrace();
}
if (array.length() != 0) {
for (int i = 0; i < array.length(); i++) {
JSONObject json_data;
try {
json_data = array.getJSONObject(i);
Category obj = new Category();
obj.Image = json_data.getString("Product_Image");
obj.Title = json_data.getString("Price");
categorylist.add(obj);
} catch (JSONException e) {
e.printStackTrace();
}
}
} else {}
} catch (ClientProtocolException e) {
} catch (IOException e) {
}
return r;
}
Class Adapter
public class Category_Adapter extends BaseAdapter {
public String[] items;
public LayoutInflater myinflater;
Context context;
static class ViewHolder
{
TextView text;
TextView price;
ImageView im;
}
public int[] picmenu;
ArrayList<Category> categorylist = new ArrayList<Category>();
public Category_Adapter(Context c, ArrayList<Category> pthemop) {
myinflater = LayoutInflater.from(c);
context = c;
categorylist = pthemop;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return categorylist.size();
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent)
{
final ViewHolder holder;
// /////
if (convertView == null) {
convertView = myinflater.inflate(R.layout.snipper_single, null);
holder = new ViewHolder();
holder.text = (TextView) convertView.findViewById(R.id.text);
holder.im = (ImageView) convertView.findViewById(R.id.image);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.text.setText(categorylist.get(position).Title);
Picasso.with(context).load(categorylist.get(position).Image)
.into(holder.im);
return convertView;
}}
Class Category
public class Category {
String Title;
String Image;
}
Here:
spinner.setAdapter(new Category_Adapter(getActivity(), categorylist));
line causing issue because spinner object of Spinner is null.
In onCreateView method creating new object instead of initializing object which is using in spinner.
Change onCreateView method as:
spinner = (Spinner) rootView.findViewById(R.id.category);
new fechPosts().execute("");

listview is jerking on scrolling

i hv an application in which i am getting data from api,when data get loads and i tried to scroll the listview it get starts jerking,i tried to find the solution but get nothing.please help me to sort it out.
InboxActivity.java
list=(ListView)rootView.findViewById(R.id.list);
catagery = new ArrayList<ProfileInbox>();
String fontPath = "font/Roboto-Regular.ttf";
// Loading Font Face
Typeface tf = Typeface.createFromAsset(getActivity().getAssets(), fontPath);
list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View arg1,
int position, long id) {
// TODO Auto-generated method stub
//arg0.getp.setBackgroundColor(Color.WHITE);
//parent.getChildAt(position).setBackgroundColor(Color.BLUE);
IsRead=true;
catagery.get(position).setRead(IsRead);
new Task().execute(url);
adapter.notifyDataSetChanged();
msg=catagery.get(position).getMessage();
dateFrom=catagery.get(position).getSentDate();
sub=catagery.get(position).getSubject();
Intent i= new Intent(getActivity(),InboxDetail.class);
startActivity(i);
}
});
return rootView;
}
private void loadNextPageOfReviews()
{
page_no_count += 1;
new JSONAsyncTask().execute(loadMoreUrl);
}
class JSONAsyncTask extends AsyncTask<String, Void, Boolean> {
ProgressDialog dialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog = new ProgressDialog(getActivity());
dialog.setMessage("Please Wait, Loading...");
dialog.show();
dialog.setCancelable(false);
}
#Override
protected Boolean doInBackground(String... urls) {
try {
// ------------------>>
HttpGet httppost = new HttpGet(urls[0]);
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = httpclient.execute(httppost);
// StatusLine stat = response.getStatusLine();
int status = response.getStatusLine().getStatusCode();
if (status == 200) {
HttpEntity entity = response.getEntity();
String data = EntityUtils.toString(entity);
JSONObject jsono = new JSONObject(data);
JSONArray jarray = jsono.getJSONArray("inbox");
String unread_msg= jsono.getString("unread_msg");
Log.i("unreadMsg", unread_msg);
for (int i = 0; i < jarray.length(); i++) {
JSONObject c = jarray.getJSONObject(i);
ProfileInbox category = new ProfileInbox();
String id = c.getString("msg_id");
String sub = c.getString("subject");
String name = c.getString("message");
String imageSetter=c.getString("sent_on");
//Log.i("id", id);
//Log.i("name", name);
//Log.i("imageSetter", imageSetter);
category.setMsgId(((JSONObject) c).getString("msg_id"));
if(unread_msg.contains(id)){
category.setRead(false);
}
else{
category.setRead(true);
}
category.setSubject(((JSONObject) c).getString("subject"));
category.setMessage(((JSONObject) c).getString("message"));
category.setSentDate(((JSONObject) c).getString("sent_on"));
//Log.i("category", category.toString());
catagery.add(category);
//Log.i("category", category.toString());
}
return true;
}
// ------------------>>
} catch (ParseException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return false;
}
protected void onPostExecute(Boolean result) {
dialog.cancel();
if (result == false){
Toast.makeText(getActivity(),
"Unable to fetch data from server", Toast.LENGTH_LONG)
.show();
}
else if(Blank.notice.equals("true")){
msg=catagery.get(0).getMessage();
dateFrom=catagery.get(0).getSentDate();
sub=catagery.get(0).getSubject();
adapter = new InboxAdaptor(getActivity(),
catagery);
list.setAdapter(adapter);
adapter.notifyDataSetChanged();
Intent i= new Intent(getActivity(),InboxDetail.class);
startActivity(i);
}
else if(Blank.notice.equals("false"))
{
//adapter.notifyDataSetChanged();
adapter = new InboxAdaptor(getActivity(),
catagery);
list.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
}
InboxAdapter
public class InboxAdaptor extends BaseAdapter {
private List<ProfileInbox> originalData;
private List<ProfileInbox> filteredData;
private Context context;
public static String url;
public static String bussinessId;
public InboxAdaptor(Context context, ArrayList<ProfileInbox> Data) {
this.context = context;
this.originalData = Data;
//Log.i("originalData", Data.toString());
filteredData = new ArrayList<ProfileInbox>();
filteredData.addAll(this.originalData);
//Log.i("filterData", filteredData.toString());
}
#Override
public int getCount() {
return filteredData.size();
}
#Override
public Object getItem(int position) {
return filteredData.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = LayoutInflater.from(context).inflate(R.layout.inboxlist, null,false);
holder.coloredlay=(RelativeLayout)convertView.findViewById(R.id.coloredlay);
holder.txtWelcom = (TextView) convertView.findViewById(R.id.txtWelcom);
holder.dateTime = (TextView) convertView.findViewById(R.id.dateTime);
holder.txtdetails = (TextView) convertView.findViewById(R.id.txtdetails);
convertView.setTag(holder);
} else {
holder = (ViewHolder)convertView.getTag();
}
if(filteredData.get(position).getRead()==true)
{
holder.coloredlay.setBackgroundColor(Color.WHITE);
notifyDataSetChanged();
}else{
holder.coloredlay.setBackgroundColor(Color.parseColor("#E5E4E2"));
}
// holder.img.setTag(position);
String fontPath = "font/Roboto-Regular.ttf";
// Loading Font Face
Typeface tf = Typeface.createFromAsset(convertView.getContext().getAssets(), fontPath);
holder.txtWelcom.setText(filteredData.get(position).getSubject());
holder.txtWelcom.setTypeface(tf);
holder.dateTime.setText(filteredData.get(position).getSentDate());
holder.dateTime.setTypeface(tf);
holder.txtdetails.setText(filteredData.get(position).getMessage());
holder.txtdetails.setTypeface(tf);
/* if(Blank.notice.equals("true")){
holder.coloredlay.setBackgroundColor(Color.WHITE);
notifyDataSetChanged();
}
*/
notifyDataSetChanged();
return convertView;
}
public static class ViewHolder {
public RelativeLayout coloredlay;
public TextView txtdetails;
public TextView dateTime;
public TextView txtWelcom;
}
Remove notifyDataSetChanged() from getView() , notifyDataSetChanged() will update adapter when the data which you provided for your adapter has been changed , but you are using that wrong when a View of your list has been changed.
Remove notifyDataSetChanged() from getView().
You dot need that here. Rather have Remove notifyDataSetChanged() in onPostExecute() call back of JSONAsyncTask
Use cachecolorHint for come out of your solution:
<ListView
android:id="#+id/listNewsMain"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:cacheColorHint="#android:color/transparent" >
</ListView>

how to maintain scroll position of listview when it updates

I have read plenty of examples ,but if I wish to maintain my scroll position after a ListView is updated from JSON ,then can I do that without using an AsyncTask instance ???
the code for my list is
String wrd;
//ArrayList<HashMap<String,String>> mylist;
#Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent i2=getIntent();
wrd=i2.getStringExtra("entrd");
Log.v("keyis",wrd);
final Handler handler = new Handler();
Runnable runable = new Runnable() {
#Override
public void run() {
//call the function
LoadData();
//also call the same runnable
handler.postDelayed(this, 40000);
}
};
handler.postDelayed(runable, 10);
}public void LoadData(){
JSONObject j2=JSONfunctions.getJSONfromURL("/webservice_search.php?keyword="+wrd+"&format=json");
ArrayList<HashMap<String,String>> mylist = new ArrayList<HashMap<String,String>>();
try{JSONArray jray=j2.getJSONArray("listings");
for(int i=0;i<jray.length();i++){
Log.v("state","json data being read");
JSONObject j3= jray.getJSONObject(i);
String first=j3.getString("listing");
Log.v("sublist", first);
JSONObject j4=j3.getJSONObject("listing");
String sec=j4.getString("links");
int maxLength = (sec.length() < 30)?sec.length():27;
sec.substring(0, maxLength);
String cutsec=sec.substring(0,maxLength);
Log.v("links are",cutsec);
String img=j4.getString("image_name");
Log.v("image name is ",img);
//Uri dimg=Uri.parse("http://zeesms.info/android_app_images/Koala.jpg");
HashMap<String,String> map=new HashMap<String,String>();
map.put("Id",String.valueOf(i));
map.put(Li_nk,cutsec);
map.put(Image_name,j4.getString("image_name"));
map.put(KEY_THUMB_URL,"http://zeesms.info/android_app_images/"+img);
mylist.add(map);
}
}
catch(JSONException e){
Log.e("loG_tag","Error parsing"+e.toString());
}
LazyAdapter adapter = new LazyAdapter(this,mylist);
adapter.notifyDataSetChanged();
ListView list=(ListView)findViewById(R.id.lv1);
list.setEmptyView(findViewById(R.id.empty));
list.setAdapter(adapter);
list.setItemsCanFocus(false);
and my adapter is
public class LazyAdapter extends BaseAdapter {
private Activity activity;
private ArrayList<HashMap<String, String>> data;
private static LayoutInflater inflater=null;
public ImageLoader imageLoader;
public LazyAdapter(Activity a, ArrayList<HashMap<String, String>> d) {
activity = a;
data=d;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader=new ImageLoader(activity.getApplicationContext());
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return data.size();
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View vi=convertView;
if(convertView==null)
vi = inflater.inflate(R.layout.custom_row_view1, null);
TextView title = (TextView)vi.findViewById(R.id.linkname); // merchnts name
TextView artist = (TextView)vi.findViewById(R.id.imagename); // address
//TextView duration = (TextView)vi.findViewById(R.id); // distance
ImageView thumb_image=(ImageView)vi.findViewById(R.id.mClogo); // logo
HashMap<String, String> jsn = new HashMap<String, String>();
jsn = data.get(position);
// Setting all values in listview
title.setText(jsn.get(Second.Li_nk));
artist.setText(jsn.get(Second.Image_name));
//duration.setText(song.get(CustomizedListView.KEY_DURATION));
imageLoader.DisplayImage(jsn.get(Second.KEY_THUMB_URL), thumb_image);
return vi;
}
and finally the class being used for json parsing is
public class JSONfunctions {
public static JSONObject getJSONfromURL(String url){
InputStream is = null;
String result = "";
JSONObject jArray = null;
String str1="http://zeesms.info"+url;
// ArrayList<NameValuePair> namevaluepairs = new ArrayList<NameValuePair>();
Log.v("url result",url);
//namevaluepairs.add(new BasicNameValuePair("location",str1));
//http post
try{
HttpClient httpclient= new DefaultHttpClient();
HttpGet request = new HttpGet();
request.setURI(new URI(str1));
HttpResponse response = httpclient.execute(request);
is = response.getEntity().getContent();
if(is==null){
Log.v("url result","is null");
}
else
{
Log.v("url result","is not null");
}
/* BufferedReader buf = new BufferedReader(new InputStreamReader(is,"UTF-8"));
StringBuilder sb = new StringBuilder();
String s;
while(true )
{
s = buf.readLine();
if(s==null || s.length()==0)
break;
sb.append(s);
}
buf.close();
is.close();
sb.toString(); */
// httppost.setEntity(new UrlEncodedFormEntity(namevaluepairs));
//HttpResponse response=httpclient.execute(httppost);
//HttpEntity entity=response.getEntity();
//is=entity.getContent();
/*
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
*/
}catch(Exception e){
Log.v("log_tag", "Error in http connection "+e.toString());
AlertDialog.Builder alert=new AlertDialog.Builder(null);
alert.setMessage("Invalid Keyword").setPositiveButton("Ok", new OnClickListener(){
#Override
public void onClick(DialogInterface arg0, int arg1) {
// TODO Auto-generated method stub
}
});
}
//convert response to string
try{
Log.v("url result","getting result starts");
BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
StringBuilder sb = new StringBuilder();
String line = null;
Log.v("url result","getting result");
while ((line = reader.readLine()) != null) {
Log.v("url result","getting result");
sb.append(line + "\n");
}
is.close();
result=sb.toString();
Log.v("url result",result);
}catch(Exception e){
Log.e("log_tag", "Error converting result "+e.toString());
}
try{
jArray = new JSONObject(result);
}catch(JSONException e){
Log.e("log_tag", "Error parsing data "+e.toString());
}
return jArray;
}
}
along with this if the data is updated from the webpage, what would be the simplest way to show the updated item on top ??
It is easier to maintain scroll position by calling notifydatasetchanged() only. The problem there is that you are creating a new adapter every time the data gets updated... you should do something like this:
if(listView.getAdapter()==null)
listView.setAdapter(myAdapter);
else{
myAdapter.updateData(myNewData); //update adapter's data
myAdapter.notifyDataSetChanged(); //notifies any View reflecting data to refresh
}
This way, your listview will mantain the scrolling position.
In case you want to scroll to a new position, use:
list.smoothScrollToPosition(int position);
In case for some reason you don't want to call notifyDataSetChanged(), the you can maintain the position by using setSelectionFromTop()
Before updating the adaptor:
lastViewedPosition = listView.getFirstVisiblePosition();
//get offset of first visible view
View v = listView.getChildAt(0);
topOffset = (v == null) ? 0 : v.getTop();
After updating the adaptor:
listView.setSelectionFromTop(lastViewedPosition, topOffset);
list.smoothScrollToPosition(int position); //my favorite :)
It may also help you to scroll nice'n'smooth to a particular item
listview.setSelection( i );
this will help you to set particular row at top
For overall picture:
In your API response callback, call this function(example) below:
MyAdapter mAdapter;
ArrayList<Users> mUsers;
private void updateListView(ArrayList<Users> users) {
mUsers.addAll(users);
if(mAdapter == null) {
mAdapter = new MyAdapter(getContext(), mUsers);
mListView.setAdapter(mAdapter);
}
mAdapter.notifyDataSetChanged(); // Add this one
}
If you're using an ArrayAdapter (or a subclass of it), the problem may be caused by that the adapter updates the list when you clean it before adding the new items:
adapter.clear();
adapter.addAll(...);
You can fix it by wrapping the code that modifies the adapter like this:
adapter.setNotifyOnChange(false); // Disable calling notifyDatasetChanged() on modification
adapter.clear();
adapter.addAll(...); // Notify the adapter about that data has changed. Note: it will re-enable notifyOnChange
adapter.notifyDataSetChanged();

Categories

Resources