I currently have a ListView Which is being populated by a SimpleAdapter and the population is working great. Problem I am having is I cant seem to figure out how to change the background color of the ListItem LinearLayout during the onCreate. It is working perfectly fine if I click a button or do an action psychically but does not want to work if i do it in the onCreate or if I do it after populating the ListView based off of all the tables in my SQLITE database.
This code is what is changing the color.
if(c.moveToFirst()){
do{
if(checkCat.moveToFirst()){
do{
if(c.getString(0).equals(checkCat.getString(0))){
for (int i = 0; i < adapter.getCount(); i++) {
final FrameLayout listItemLayout = (FrameLayout) cardList.getChildAt(i);
final LinearLayout lL = (LinearLayout) listItemLayout.findViewById(R.id.cardmainlayout);
final TextView tv = (TextView) listItemLayout.findViewById(R.id.text1);
if(tv.getText().toString().equals(checkCat.getString(1).trim())) {
switch (c.getString(1).trim()) {
case "White":
lL.setBackgroundResource(R.drawable.bg_color_white);
break;
case "Orange":
lL.setBackgroundResource(R.drawable.bg_color_orange);
break;
case "Red":
lL.setBackgroundResource(R.drawable.bg_color_red);
break;
case "Green":
lL.setBackgroundResource(R.drawable.bg_color_green);
break;
case "Purple":
lL.setBackgroundResource(R.drawable.bg_color_purple);
break;
case "Blue":
lL.setBackgroundResource(R.drawable.bg_color_blue);
break;
}
switch (c.getString(2).trim()) {
case "White":
tv.setTextColor(getResources().getColor(android.R.color.white));
break;
case "Black":
tv.setTextColor(getResources().getColor(android.R.color.black));
break;
case "Green":
tv.setTextColor(getResources().getColor(android.R.color.holo_green_dark));
break;
case "Orange":
tv.setTextColor(getResources().getColor(android.R.color.holo_orange_dark));
break;
case "Red":
tv.setTextColor(getResources().getColor(android.R.color.holo_red_dark));
break;
case "Blue":
tv.setTextColor(getResources().getColor(android.R.color.holo_blue_dark));
break;
}
}
}
}
}while (checkCat.moveToNext());
}
}while(c.moveToNext());
}
This code is what is populating the ListView
if (c.moveToFirst()) {
do {
if (!c.getString(0).contains("a")) {
if (!c.getString(0).contains("name")) {
if (!c.getString(0).contains("name2")) {
String str = c.getString(0);
map = new HashMap<String, Object>();
map.put("title", str.toString();
fillMaps.add(map);
}
}
}
} while (c.moveToNext());
}
Also have this code which reupdates the ListView Based on categories the code is sort of working here. Problem is the first part is the same as above so it crashes and the second part does not exactly update after the adpater is refreshed. you have to click it the category button again for it to detect the adapter changed.(yes I am calling the adapter.notifyDataSetChanged().)
if(strName.toLowerCase().equals("all")) {
fillMaps.clear();
Cursor c = appDB.rawQuery("SELECT name FROM sqlite_master WHERE type='table';", null);
if (c.moveToFirst()) {
do {
if (!c.getString(0).contains("android_metadata")) {
if (!c.getString(0).contains("Name1")) {
if (!c.getString(0).contains("Name")) {
map = new HashMap<String, Object>();
map.put("title", c.getString(0));
fillMaps.add(map);
chkBox = 0;
}
}
}
} while (c.moveToNext());
}
}
else {
Cursor checkCat = appDB.rawQuery("SELECT * FROM Name", null);
if (checkCat.moveToFirst()) {
fillMaps.clear();
do {
if (checkCat.getString(0).contains(strName)) {
map = new HashMap<String, Object>();
map.put("title", checkCat.getString(1));
fillMaps.add(map);
chkBox = 0;
}
} while (checkCat.moveToNext());
}
}
adapter.notifyDataSetChanged();
and last but not least this is my SimpleAdapter
adapter = new SimpleAdapter(this, fillMaps, R.layout.main_c_layout, from, to) {
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View rRow = super.getView(position, convertView, parent);
final Button vsButton = (Button) rRow.findViewById(R.id.quizListViewButton);
final CheckBox cb = (CheckBox) rRow.findViewById(R.id.deleteCheckBox);
TextView v = (TextView) rRow.findViewById(R.id.text1);
final String str = v.getText().toString().replaceFirst("\\s+$", "");
vsButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, str + "", Toast.LENGTH_SHORT).show();
}
});
cb.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (cb.isChecked()) {
chkBox++;
} else {
chkBox--;
}
if (chkBox > 1) {
editNoteSet.setVisibility(View.GONE);
} else {
editNoteSet.setVisibility(View.VISIBLE);
}
}
});
return rRow;
}
};
List.setAdapter(adapter);
So just to clear my question up how would you change the color of the LinearLayout that is located within the Custom ListView row.(For the record everything is populating properly I just cannot change the color.)
Also, The error I keep getting is Attempt to invoke virtual method 'android.view.View android.widget.FrameLayout.findViewById(int)' on a null object reference
which makes not sense because it works when I click a button or do an action physically. Any and all help is appreciated Thank you in advance.
Solution:
Thanks to Mehrdad1373 I was able to come up with the solution. So the solution was to actually change the background in the SimpleAdapter getView method. I didn't realize that the simple adapter was getting called everytime a row was removed or added. So this is what I did..
adapter = new SimpleAdapter(this, fillMaps, R.layout.main_c_layout, from, to) {
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View rRow = super.getView(position, convertView, parent);
final Button vsButton = (Button) rRow.findViewById(R.id.quizListViewButton);
final CheckBox cb = (CheckBox) rRow.findViewById(R.id.deleteCheckBox);
LinearLayout lL = (LinearLayout)rRow.findViewById(R.id.myLayout);
TextView v = (TextView) rRow.findViewById(R.id.text1);
final String str = v.getText().toString().replaceFirst("\\s+$", "");
If(str.equals(c.getString(0)){
lL.setBackgroundColor(Color.Blue);
}else{
lL.setBackgroundColor(Color.Green);
}
vsButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, str + "", Toast.LENGTH_SHORT).show();
}
});
cb.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (cb.isChecked()) {
chkBox++;
} else {
chkBox--;
}
if (chkBox > 1) {
editNoteSet.setVisibility(View.GONE);
} else {
editNoteSet.setVisibility(View.VISIBLE);
}
}
});
return rRow;
}
};
List.setAdapter(adapter);
you should put this code in getView() in SimpleAdapter
Here is what you need to do :
LayoutInflater inflater=context.getLayoutInflater();
View rowView=inflater.inflate(R.layout.mylist, null,true);
rowView.setBackgroundColor(Color.BLUE);//You Can define your own color by using Color.argb()
note that mylist is the name of xml layout that defines your list's content
Try to call the function that changes the background inside OnGlobalLayoutListener
listView.getViewTreeObserver().addOnGlobalLayoutListener(
new OnGlobalLayoutListener() {
#SuppressLint("NewApi")
#SuppressWarnings("deprecation")
#Override
public void onGlobalLayout() {
if (!Build.JELLY_BEAN_COMPATIBILITY) {
listView.getViewTreeObserver()
.removeGlobalOnLayoutListener(this);
} else {
listView.getViewTreeObserver()
.removeOnGlobalLayoutListener(this);
}
yourFunctionHere();
}
});
}
Related
I have a ListView with many items. Each item has a button and when I click on it, it becomes invisible and another button becomes visible.
The issue is: when I scroll the ListView, many other items buttons are invisible. How can I fix it?
public class homebuyer_fruits_adapter extends BaseAdapter {
private ArrayList<Itemssetget> listData;
private LayoutInflater layoutInflater;
public static int cout=0;
List position_item=new ArrayList();
Context context;
String check;
int lastpostition=-1;
public static List<cartitemslist> cartlist=new ArrayList<>();
public homebuyer_fruits_adapter(Context aContext, ArrayList<Itemssetget> listData,String number) {
this.listData = listData;
layoutInflater = LayoutInflater.from(aContext);
context=aContext;
check=number;
this.notifyDataSetChanged();
}
public int getCount() {
return listData.size();
}
#Override
public Object getItem(int position) {
return listData.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View v, ViewGroup parent) {
final ViewHolder holder;
final cartitemslist homeitemslist = new cartitemslist();
if (v == null) {
v = layoutInflater.inflate(R.layout.food_vegitablews_view, null);
holder = new ViewHolder();
holder.name = (TextView) v.findViewById(R.id.name_item);
holder.price = (TextView) v.findViewById(R.id.price_item);
holder.add_q = (ImageView) v.findViewById(R.id.add_quantity);
holder.delete_q = (ImageView) v.findViewById(R.id.delete_quantity);
holder.quantity = (TextView) v.findViewById(R.id.add_quantity_items);
//holder.description = (TextView) v.findViewById(R.id.description_item);
//holder.id = (TextView) v.findViewById(R.id.);
holder.imageView = (ImageView) v.findViewById(R.id.image_items);
holder.discount = (TextView) v.findViewById(R.id.discout_price);
holder.add = (Button) v.findViewById(R.id.addto_cart);
holder.units=(TextView)v.findViewById(R.id.item_units);
holder.percentage=(TextView)v.findViewById(R.id.discount_percentage);
holder.linearLayou=(LinearLayout)v.findViewById(R.id.Quantity_control_linnear_view) ;
holder.phone=check;
v.setTag(holder);
} else {
holder = (ViewHolder) v.getTag();
this.notifyDataSetChanged();
}
int i=Integer.parseInt(listData.get(position).getPrice())-Integer.parseInt(listData.get(position).getDiscountprice());
int d=i*100;
if((d/Integer.parseInt(listData.get(position).getPrice()))==0)
{
holder.percentage.setVisibility(View.GONE);
}
holder.percentage.setText(""+d/Integer.parseInt(listData.get(position).getPrice())+"% OFF");
holder.name.setText(listData.get(position).getName());
holder.price.setText("Rs " + listData.get(position).getPrice());
if(listData.get(position).getPrice().equals(listData.get(position).getDiscountprice()))
{
holder.price.setVisibility(View.GONE);
}
holder.price.setPaintFlags(holder.price.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
holder.discount.setText("Rs " + listData.get(position).getDiscountprice());
Picasso.with(context).load(listData.get(position).getImageurl())
.fit().centerCrop().into(holder.imageView);
holder.units.setText(listData.get(position).getUnits());
holder.add_q.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Toast.makeText(context,listData.get(position).getName(),Toast.LENGTH_LONG).show();
if(H.containsKey(position))
{
holder.quantity.setText(""+(1+Integer.parseInt(holder.quantity.getText().toString())));
cartlist.get(H.get(position)).setQuantity(holder.quantity.getText().toString());
}
}
});
holder.delete_q.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(H.containsKey(position)) {
if(holder.quantity.getText().toString().equals("1"))
{
holder.add.setVisibility(View.VISIBLE);
holder.linearLayou.setVisibility(View.GONE);
int i=H.get(position);
cartlist.remove(i);
cout--;
Fruits.numberofitems.setText(cout + "");
}
else {
holder.quantity.setText("" + (Integer.parseInt(holder.quantity.getText().toString()) - 1));
cartlist.get(H.get(position)).setQuantity(holder.quantity.getText().toString());
}
}
}
});
holder.add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Toast.makeText(context,"Add to cart"+holder.name.getText(),Toast.LENGTH_SHORT).show();
holder.add.setVisibility(View.GONE);
holder.linearLayou.setVisibility(View.VISIBLE);
// check=listData.get(position).getPhonenumber_seller();
if(cartlist.isEmpty()) {
cout++;
homeitemslist.setName(holder.name.getText().toString());
homeitemslist.setPrice(holder.price.getText().toString());
homeitemslist.setDiscountp(holder.discount.getText().toString());
homeitemslist.setQuantity(holder.quantity.getText().toString());
homeitemslist.setPhone_id(holder.phone);
homeitemslist.setImage(listData.get(position).getImageurl());
if(Fruits.numberofitems!=null)
{
Fruits.numberofitems.setText(cout + "");
}
shop_items.numberofitems.setText(cout + "");
buyer_home.numberofitems.setText(cout + "");
cartlist.add(homeitemslist);
H.put(position,cartlist.indexOf(homeitemslist));
}
else {
if(check.equals(cartlist.get(0).getPhone_id()))
{
cout++;
cartitemslist homeitemslist = new cartitemslist();
homeitemslist.setName(holder.name.getText().toString());
homeitemslist.setPrice(holder.price.getText().toString());
homeitemslist.setDiscountp(holder.discount.getText().toString());
homeitemslist.setQuantity(holder.quantity.getText().toString());
homeitemslist.setPhone_id(holder.phone);
homeitemslist.setImage(listData.get(position).getImageurl());
if(Fruits.numberofitems!=null)
{
Fruits.numberofitems.setText(cout + "");
}
shop_items.numberofitems.setText(cout + "");
buyer_home.numberofitems.setText(cout + "");
cartlist.add(homeitemslist);
H.put(position,cartlist.indexOf(homeitemslist));
}
else
{
Toast.makeText(context,"Clear the Previous cart First than you can buy from this shop",Toast.LENGTH_LONG).show();
}
}
}
});
// holder.description.setText(listData.get(position).getDiscription());
// holder.id.setText(listData.get(position).getId());
//holder.imageView.setImageAlpha(R.drawable.banana);
setanimation(v,position);
return v;
}
static class ViewHolder {
LinearLayout linearLayou;
TextView name;
TextView price;
TextView discount;
ImageView add_q;
ImageView delete_q;
TextView quantity;
ImageView imageView;
TextView description;
TextView units;
TextView percentage;
String phone;
Button add;
}
public void setanimation(View viewanim,int position)
{
if(position>lastpostition)
{
ScaleAnimation animation=new ScaleAnimation(0.0f,1.0f,0.0f,1.0f,
Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
animation.setDuration(1500);
viewanim.setAnimation(animation);
lastpostition=position;
}
}
}
Here is my adapter code.
I tried many ways but still stuck on this issue.
You set the visibility only in the OnClickListener, but you need to set it in getView() too, because your views will get recycled (re-used for a different item) when you scroll.
So in getView() you have to restore the complete state of the view, including button visibility. Store all state information in your list items. Inside your getView() do something like this:
#Override
public View getView(final int position, View v, ViewGroup parent) {
...
// the view (v) could be recycled and showing a state from another item
// e.g. the add button is visible
final Itemssetget listItem = listData.get(position);
// so we have to restore the state of the view for listItem above
// e.g. update the button visibility
holder.add.setVisibility(listItem.isAddButtonVisible() ? View.VISIBLE : View.GONE);
holder.add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
...
holder.add.setVisibility(View.GONE);
// save the state of the button, so it can be restored later
listItem.setAddButtonVisible(true);
...
}
}
...
}
Add the necessary member variables and getter/setter functions in Itemssetget:
public class Itemssetget {
...
private boolean isAddButtonVisible = false;
public boolean isAddButtonVisible() {
return isAddButtonVisible;
}
public void setAddButtonVisible(boolean isVisible) {
this.isAddButtonVisible = isVisible;
}
...
}
PS: Your code looks terrible. Have a look at naming conventions.
I am having trouble getting the entire string put into my arraylist correctly. I am assuming the error has something to do with my custom textwatcher or how I am looping through the array list. Here is my code:
case R.id.action_add:
Workout workout = new Workout("", "", "", "");
workoutList.add(workout);
ListView exerciseList = (ListView) findViewById(R.id.exerciseListView);
CustomAdapter myAdapter = new CustomAdapter(this, R.layout.custom_list, workoutList);
exerciseList.setAdapter(myAdapter);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public class CustomAdapter extends ArrayAdapter<Workout> {
private int layoutResource;
public CustomAdapter(Context context, int layoutResource, List<Workout> workoutList) {
super(context, layoutResource, workoutList);
this.layoutResource = layoutResource;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
LayoutInflater layoutInflater = LayoutInflater.from(getContext());
view = layoutInflater.inflate(layoutResource, null);
}
Workout workout = getItem(position);
if (workout != null) {
final EditText exercise = (EditText) view.findViewById(R.id.exercise);
final EditText reps = (EditText) view.findViewById(R.id.reps);
final EditText sets = (EditText) view.findViewById(R.id.sets);
if (exercise != null){
exercise.addTextChangedListener(new CustomWatcher(exercise));
}
if (reps != null) {
reps.addTextChangedListener(new CustomWatcher(reps));
}
if (sets != null) {
sets.addTextChangedListener(new CustomWatcher(sets));
}
}
return view;
}
}
//Textwatcher class
class CustomWatcher implements TextWatcher {
private View view;
public CustomWatcher(View view) {
this.view = view;
}
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
public void afterTextChanged(Editable editable) {
String text = editable.toString();
switch (view.getId()) {
//exercises
case R.id.exercise:
exercises.add(text);
break;
//reps
case R.id.reps:
reps.add(text);
break;
//sets
case R.id.sets:
sets.add(text);
break;
}
}
}
}
The cases are buttons. So when I click the add button I am trying to add my custom list view to my page which includes three text views. Then when I click save I am trying to get it to save the data from each edit text position into an array list to store into my data base.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection for menu
switch (item.getItemId()) {
case R.id.action_save:
String title = MyWorkoutsActivity.workouts.get(workoutID);
String ex;
String rp;
String st;
SQLDatabase db = new SQLDatabase(this);
for(int i = 0; i < workoutList.size(); i++){
//exercises, reps, and sets always same number so only one for loop needed
ex = exercises.get(i);
rp = reps.get(i);
st = sets.get(i);
db.addExercise(new Workout(title, ex, rp, st));
}
List<Workout> workouts = db.getAllExercises();
for (Workout wo : workouts) {
String log = "Workout " + wo.getWorkout() + "Exercise " + wo.getExercise() + " ,Reps " + wo.getReps() + " ,Sets " + wo.getSets();
// Writing workouts to log
Log.d("Workout ", log);
}
Intent intent = new Intent(this, MyWorkoutsActivity.class);
startActivity(intent);
return true;
This is happening because the listener method afterTextChanged is lunched after the first letter typed in so it will save the first letter into the list and so on
until you end up with a list of characters.
the solution is : simply don't use the textwatcher because you want to save the data when the user presses the save button so add the data to the exercises list when the button is hit like this code :
public void onClick(View view){
//the exercise and reps and sets are the EditText fields that you have
exercises.add(exercise.getText());
exercises.add(reps.getText());
exercises.add(sets.getText());
}
So, What I want to do is display chats in my activity using a custom list view adapter.
I have a HTTPTask Activity handling the server side interaction and responding with a JSONObject. So, every server side interaction is working fine.
What I want to do is keep updating the messages in the chat by keep checking with the API at a set interval to populate messages in the chat if there are any.
My question is, should this population process done in the adapter or the activity and how?
And, how does viewHolder help in the adapter?
This is my Activity
public class ChatActivity extends Activity {
TextView toUsername;
EditText replyText;
JSONObject resultObject;
StringBuilder reply,from_user_id,c_id;
MessageListViewAdapter myAdapter;
ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
toUsername = (TextView) findViewById(R.id.toUsername);
replyText = (EditText) findViewById(R.id.replyText);
reply = new StringBuilder("");
listView = (ListView) findViewById(R.id.messages);
}
#Override
public void onResume(){
super.onResume();
Bundle bundle = getIntent().getExtras();
if(bundle != null){
toUsername.setText("" + bundle.get("ToUsername").toString());
c_id = new StringBuilder(bundle.get("c_id").toString());
from_user_id = new StringBuilder(bundle.get("FromUserId").toString());
}
myAdapter = new MessageListViewAdapter(getBaseContext(),c_id.toString(),from_user_id.toString());
listView.setAdapter(myAdapter);
}
public void sendTextMsg(View view){
reply.delete(0,reply.length());
reply.append(replyText.getText().toString());
if(!reply.toString().equals("")){
Log.d("Values: ","c_id: " + c_id.toString() + " FromUserId: " + from_user_id.toString() + "ReplyText: " + reply.toString());
try{
resultObject = new HttpTask(getBaseContext()).doInBackground("replyInChat",c_id.toString(),replyText.getText().toString(),from_user_id.toString());
if(resultObject.get("status").toString().equals("true")) {
Toast.makeText(getBaseContext(), "Sent.", Toast.LENGTH_SHORT).show();
replyText.setText("");
}
else {
Toast.makeText(getBaseContext(), "Try Again.", Toast.LENGTH_SHORT).show();
}
}
catch(JSONException e){ }
}
}
}
My Adapter doesn't seem to work.
public class MessageListViewAdapter extends BaseAdapter implements ListAdapter{
private ArrayList<String> list = new ArrayList<String>();
private Context context;
private StringBuilder conversation_id, user_id;
private static int cr_id;
private JSONArray messages;
private JSONObject resultObject;
private ViewHolder viewHolder;
private View rowView;
public MessageListViewAdapter(Context context, String conversation_id, String user_id) {
this.context = context;
this.conversation_id = new StringBuilder(conversation_id.toString());
this.user_id = new StringBuilder(user_id.toString());
cr_id=0;
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int pos) {
return list.get(pos);
}
#Override
public long getItemId(int pos) {
//return list.get(pos).getId();
//just return 0 if your list items do not have an Id variable.
return 0;
}
#Override
public boolean isEnabled(int position){
return false;
}
static class ViewHolder{
public TextView ItemText;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
rowView = convertView;
if (rowView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflater.inflate(R.layout.message_list_layout, null);
//configure view holder
viewHolder = new ViewHolder();
viewHolder.ItemText = (TextView) rowView.findViewById(R.id.list_item_text);
rowView.setTag(viewHolder);
}
else {
//fill data
viewHolder = (ViewHolder) rowView.getTag();
}
try{
Log.d("cr_id: ",String.valueOf(cr_id).toString());
//This is where the population should've taken place but didn't.
resultObject = new HttpTask(context).doInBackground("sendMessages",conversation_id.toString(),String.valueOf(cr_id));
if(resultObject.get("status").toString().equals("true")) {
messages = resultObject.getJSONArray("messages");
Log.d("Messages: ",messages.toString());
for(int i=0;i<=messages.length();i++){
list.add(messages.getJSONObject(i).get("reply_text").toString());
}
}
}
catch(JSONException e){ }
//Handle TextView and display string from your list
//final TextView listItemText = (TextView)rowView.findViewById(R.id.list_item_text);
//listItemText.setText(list.get(position));
viewHolder.ItemText.setText(list.get(position));
return rowView;
}
}
If every thing is working fine and you have problem in showing latest chat message in adapter just change your code like this:
try{
Log.d("cr_id: ",String.valueOf(cr_id).toString());
//This is where the population should've taken place but didn't.
resultObject = new HttpTask(context).doInBackground("sendMessages",conversation_id.toString(),String.valueOf(cr_id));
if(resultObject.get("status").toString().equals("true")) {
messages = resultObject.getJSONArray("messages");
Log.d("Messages: ",messages.toString());
for(int i=0;i<=messages.length();i++){
list.add(messages.getJSONObject(i).get("reply_text").toString());
this.notifyDataSetChanged(); // add this line
}
}
}
catch(JSONException e){ }
Comment below for any further information
Personally i would do the network calls outside of the adapter. With the code currently if the user was to scroll up and down the list the network call would call multiple times which is something im sure you dont want.
What may be a better solution is having a method inside the activity that does the call, then have a timer set up that calls that method say every 2 - 3 minutes to save on the network calls, you could also add a refresh button for the user which gives them the choice of refreshing the data themselves which would just call the same method.
The View Holder design pattern can help speed up a listview and keep it smooth, Think of it this way, when the page first loads, getView will be called a number of times to fill up the list view. In the getView method you instantiate your UI widgets i.e textview = (TextView)findviewbyid. Now what the view holder does is keep a reference to these ui elements which means you wont have to keep calling findViewById.
Here is an article that explains it a bit better and go into some examples.
http://www.javacodegeeks.com/2013/09/android-viewholder-pattern-example.html
So lets say you do the network code in the activity. When you get a response you can simply add the message to the list then notifyDataSetChanged();
So, Finally I got it working with some experimentation. Many thanks to Manikanta and Andy Joyce for their valuable answers. If it weren't for them i wouldn't have gone any further from where I was stuck.
This is what I changed in my custom adapter.
public void add(ArrayList<String> list){
this.list.clear();
this.list.addAll(list);
Log.d("List: ",this.list.toString());
this.notifyDataSetChanged();
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
rowView = convertView;
if (rowView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflater.inflate(R.layout.message_list_layout, null);
//configure view holder
viewHolder = new ViewHolder();
viewHolder.ItemText = (TextView) rowView.findViewById(R.id.list_item_text);
rowView.setTag(viewHolder);
}
else {
//fill data
viewHolder = (ViewHolder) rowView.getTag();
}
viewHolder.ItemText.setText(list.get(position));
return rowView;
}
This is what I added to my activity
#Override
public void onResume(){
super.onResume();
Bundle bundle = getIntent().getExtras();
if(bundle != null){
toUsername.setText("" + bundle.get("ToUsername").toString());
c_id = new StringBuilder(bundle.get("c_id").toString());
from_user_id = new StringBuilder(bundle.get("FromUserId").toString());
//list.add(c_id.toString());
//list.add(from_user_id.toString());
}
myAdapter = new MessageListViewAdapter(getBaseContext(),c_id.toString(),from_user_id.toString());
listView.setAdapter(myAdapter);
callAsynchronousTask();
//myAdapter.add(list);
}
#Override
public void onPause(){
super.onPause();
timer.cancel();
}
public void callAsynchronousTask() {
final Handler handler = new Handler();
timer = new Timer();
TimerTask doAsynchronousTask = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
public void run() {
//list.clear();
try{
resultChatObject = new HttpTask(getBaseContext()).doInBackground("sendMessages",c_id.toString(),String.valueOf(cr_id));
if(resultChatObject.get("status").toString().equals("true")) {
//list.clear();
messages = resultChatObject.getJSONArray("messages");
Log.d("Messages: ",messages.toString());
for (int i = 0; i <= messages.length(); i++) {
list.add(messages.getJSONObject(i).get("reply_text").toString());
if (cr_id < Integer.parseInt(messages.getJSONObject(i).get("cr_id").toString()))
cr_id = Integer.parseInt(messages.getJSONObject(i).get("cr_id").toString());
}
}
}
catch (JSONException e) { }
myAdapter.add(list);
}
});
}
};
timer.schedule(doAsynchronousTask, 0, 10000); //execute in every 10000 ms
}
Cheers everyone!!!
I have A grid view. I have A row.xml, which I am inflating in Adapter class. My row xml has two layout (One is visible and another is invisible.) I am doing flip animation. As I click on the any item of gridview then flip animation is happening, and I am doing visible the hided layout, and hiding that visible layout.
The animation is working perfectly. But the issue is that as I am clicking on any item, and scrolling other items also flipping. So as I realize that I am not getting the specific position.
I tried the following code.
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View row;
final RecordHolder holder = new RecordHolder();
animation1 = AnimationUtils.loadAnimation(context, R.anim.to_middle);
animation2 = AnimationUtils.loadAnimation(context, R.anim.from_middle);
if (convertView == null) {
row = View.inflate(context, R.layout.row_phone_and_tablet1, null);
} else {
//row = View.inflate(context, R.layout.row_phone_and_tablet1, null);
row = convertView;
}
holder.frontImage = (ImageView) row.findViewById(R.id.myimage_imgvw);
holder.frontMobileName = (TextView) row.findViewById(R.id.name_txtvw);
holder.frontPrice = (TextView) row.findViewById(R.id.price_txtvw);
holder.backMobileName = (TextView) row
.findViewById(R.id.tv_device_name);
holder.descOne = (TextView) row.findViewById(R.id.tv_desc_first);
holder.descTwo = (TextView) row.findViewById(R.id.tv_desc_second);
holder.descThree = (TextView) row.findViewById(R.id.tv_desc_third);
holder.descFour = (TextView) row.findViewById(R.id.tv_desc_fourth);
holder.ccEmi = (TextView) row.findViewById(R.id.tv_price_ccemi);
holder.financeEmi = (TextView) row.findViewById(R.id.tv_price_finance);
holder.frontlayout = (LinearLayout) row.findViewById(R.id.frontlayout);
holder.backlayout = (LinearLayout) row.findViewById(R.id.backlayout);
holder.viewdetails = (Button) row.findViewById(R.id.viewdetails);
holder.tv_front_inr = (TextView) row.findViewById(R.id.tv_front_inr);
holder.tv_description = (TextView) row
.findViewById(R.id.tv_description);
holder.tv_price_ccemi_inr = (TextView) row
.findViewById(R.id.tv_price_ccemi_inr);
holder.tv_ccemi_price = (TextView) row
.findViewById(R.id.tv_ccemi_price);
holder.tv_price_finance_inr = (TextView) row
.findViewById(R.id.tv_price_finance_inr);
holder.tv_financeemi_price = (TextView) row
.findViewById(R.id.tv_financeemi_price);
holder.parentLayout = (LinearLayout) row
.findViewById(R.id.parentLayout);
final PhoneAndTabletItem phoneAndTableItem = data.get(position);
holder.viewdetails.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(context, ViewPhoneInformation.class);
i.putExtra("SKU_CODE", phoneAndTableItem.getSku_code());
context.startActivity(i);
}
});
// row.setTag(holder);
holder.frontMobileName.setText(phoneAndTableItem.getModel_name());
holder.frontPrice.setText(phoneAndTableItem.getCc_emi());
holder.backMobileName.setText(phoneAndTableItem.getModel_name());
holder.descOne.setText(phoneAndTableItem.getKey_feat_1());
holder.descTwo.setText(phoneAndTableItem.getKey_feat_2());
holder.descThree.setText(phoneAndTableItem.getKey_feat_3());
holder.descFour.setText(phoneAndTableItem.getKey_feat_4());
holder.ccEmi.setText(phoneAndTableItem.getCc_emi());
holder.financeEmi.setText(phoneAndTableItem.getFinance_emi());
holder.frontMobileName.setTypeface(tvHalvetica);
holder.frontPrice.setTypeface(tvHalvetica);
holder.backMobileName.setTypeface(tvHalvetica);
holder.descOne.setTypeface(tvHalvetica);
holder.descTwo.setTypeface(tvHalvetica);
holder.descThree.setTypeface(tvHalvetica);
holder.descFour.setTypeface(tvHalvetica);
holder.ccEmi.setTypeface(tvHalvetica);
holder.financeEmi.setTypeface(tvHalvetica);
holder.tv_front_inr.setTypeface(tvHalvetica);
holder.tv_description.setTypeface(tvHalvetica);
holder.tv_price_ccemi_inr.setTypeface(tvHalvetica);
holder.tv_ccemi_price.setTypeface(tvHalvetica);
holder.tv_price_finance_inr.setTypeface(tvHalvetica);
holder.tv_financeemi_price.setTypeface(tvHalvetica);
// here we are rotating the LinearLayout...
holder.parentLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
v.setTag(position);
// Start Array Check...
Toast.makeText(context, "onClick id: " + v.getTag(), Toast.LENGTH_SHORT).show();
if (selected_views.contains((Integer) v.getTag())) {
holder.frontlayout.clearAnimation();
holder.frontlayout.setAnimation(animation1);
holder.frontlayout.startAnimation(animation1);
HashSet hs = new HashSet();
hs.addAll(selected_views);
selected_views.clear();
selected_views.addAll(hs);
selected_views.remove((Integer) v.getTag());
notifyDataSetChanged();
isBackOfCardShowing = true;
} else {
if (selected_views.size() == 0) {
holder.frontlayout.clearAnimation();
holder.frontlayout.setAnimation(animation1);
holder.frontlayout.startAnimation(animation1);
selected_views.add((Integer) v.getTag());
notifyDataSetChanged();
array_size = selected_views.size();
isBackOfCardShowing = false;
}
else {
holder.frontlayout.clearAnimation();
holder.frontlayout.setAnimation(animation1);
holder.frontlayout.startAnimation(animation1);
selected_views.add((Integer) v.getTag());
notifyDataSetChanged();
isBackOfCardShowing = false;
}
}
// End Array Check...
animation1.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
if (isBackOfCardShowing) {
holder.frontlayout.setVisibility(View.VISIBLE);
holder.backlayout.setVisibility(View.GONE);
// holder.frontImage.setImageResource(R.drawable.accesories_dashboard);
} else {
holder.backlayout.setVisibility(View.VISIBLE);
holder.frontlayout.setVisibility(View.GONE);
// holder.frontImage.setImageResource(R.drawable.vas_dashboard);
}
holder.frontlayout.clearAnimation();
holder.frontlayout.setAnimation(animation2);
holder.frontlayout.startAnimation(animation2);
}
});
}
});
holder.parentLayout.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
String inserted="";
final String SKV_CODE = phoneAndTableItem.getSku_code().toString();
handler.open();
inserted = handler.insertData(phoneAndTableItem.getModel_name(),
phoneAndTableItem.getKey_feat_1(),
phoneAndTableItem.getKey_feat_2(),
phoneAndTableItem.getKey_feat_3(),
phoneAndTableItem.getKey_feat_4(),
phoneAndTableItem.getCc_emi(),
phoneAndTableItem.getFinance_emi(),
SKV_CODE);
handler.close();
if (inserted.equals("inserted")) {
Toast.makeText(context, " Added to Shortlist " , Toast.LENGTH_SHORT).show();
} else if(inserted.equals("error")){
Toast.makeText(context, " Already present in Shortlist " , Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(context, " Try again " , Toast.LENGTH_SHORT).show();
}
return true;
}
});
return row;
}
static class RecordHolder {
ImageView frontImage;
TextView frontMobileName;
TextView frontPrice;
TextView backMobileName;
TextView descOne;
TextView descTwo;
TextView descThree;
TextView descFour;
TextView ccEmi;
TextView financeEmi;
LinearLayout frontlayout, backlayout, parentLayout;
Button viewdetails;
TextView tv_front_inr, tv_description, tv_price_ccemi_inr,
tv_ccemi_price, tv_price_finance_inr, tv_financeemi_price;
}
This code is showing properly position, but below when I am scrolling, then still I am getting flipped other items also. Please help me.
To get the exact position of item clicked in a GridView, you need to use setOnItemClickListener on your GridView reference, example:
GridView g = (GridView) findViewById(R.id.gridView1);
g.setAdapter(new ImageAdopterShow(this)); // your custom adaptor object goes here
g.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long arg3) {
Toast.makeText(getBaseContext(), "position of item is " +position, Toast.LENGTH_SHORT).show();
}
});
This is the way i get the position of any item in my GridView. Hope this answers your question.
Your Question is kind of misleading If you can get the item position then you need to change your question for animations not working in GridView properly.
In my app, I display a check list using a ListView. Every row in my check list is represented by a model, which is an object of the ChecklistenPunkt class. There are three different types of rows:
a headline
an additional text
a question
The third type has two Buttons in it which are linked by two OnClickListeners: The first Button is for a positive answer, the second one for a negative answer. When the view is build, both of them are gray, indicating that this question is not yet answered. If the left Buttonis clicked it turns green and the second one is getting a dark gray background. If the right Button is clicked it turns red and the first one is getting a dark gray background. When a Button is clicked the answering state is saved as an ChecklistenPunktStatus. This is an Enum which has three entries (okay, not okay, not answered).
Here is a little image of the Buttons in three rows, showing the different states:
Here is my adapter code:
public class ChecklisteAdapter extends ArrayAdapter<Object> {
private List<ChecklistenPunkt> list;
private SparseArray<ChecklistenPunktStatus> sparseArray;
private Context context;
public ChecklisteAdapter(Context context, List<ChecklistenPunkt> objects) {
super(context, 0);
list = objects;
sparseArray = new SparseArray<ChecklistenPunktStatus>();
for (int i = 0; i < list.size(); i++) {
sparseArray.put(i, ChecklistenPunktStatus.NICHT_SELEKTIERT);
}
this.context = context;
}
#Override
public int getCount() {
return list.size();
}
#Override
public ChecklistenPunkt getItem(int position) {
return list.get(position);
}
#Override
public int getItemViewType(int position) {
ChecklistenPunkt p = (ChecklistenPunkt) list.get(position);
return p.getTyp();
}
#Override
public int getViewTypeCount() {
return 3;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View v = null;
int type = getItemViewType(position);
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final ViewHolder viewHolder = new ViewHolder();
switch (type) {
case Util.CHECKLISTE_FRAGE:
v = inflater.inflate(R.layout.pruefung_durchfuehren_list_item_frage, null);
viewHolder.nummer = (TextView) v.findViewById(R.id.check_nummer);
viewHolder.komponente = (TextView) v.findViewById(R.id.check_komponente);
viewHolder.funktion = (TextView) v.findViewById(R.id.check_funktion);
viewHolder.kriterium = (TextView) v.findViewById(R.id.check_kriterium);
viewHolder.erlaeuterung = (TextView) v.findViewById(R.id.check_erlaeuterung);
viewHolder.io = (Button) v.findViewById(R.id.button_i_o);
viewHolder.nio = (Button) v.findViewById(R.id.button_n_i_o);
viewHolder.io.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
viewHolder.io.setBackgroundColor(Color.GREEN);
viewHolder.io.setEnabled(false);
viewHolder.nio.setBackgroundColor(Color.GRAY);
viewHolder.nio.setEnabled(true);
sparseArray.put(position, ChecklistenPunktStatus.IN_ORDNUNG);
}
});
viewHolder.nio.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
viewHolder.nio.setBackgroundColor(Color.RED);
viewHolder.nio.setEnabled(false);
viewHolder.io.setBackgroundColor(Color.GRAY);
viewHolder.io.setEnabled(true);
sparseArray.put(position, ChecklistenPunktStatus.NICHT_IN_ORDNUNG);
}
});
ChecklistenPunktStatus status = sparseArray.get(position);
if (status == ChecklistenPunktStatus.IN_ORDNUNG) {
viewHolder.io.setBackgroundColor(Color.GREEN);
viewHolder.io.setEnabled(false);
viewHolder.nio.setBackgroundColor(Color.GRAY);
viewHolder.nio.setEnabled(true);
} else if (status == ChecklistenPunktStatus.NICHT_IN_ORDNUNG) {
viewHolder.nio.setBackgroundColor(Color.RED);
viewHolder.nio.setEnabled(false);
viewHolder.io.setBackgroundColor(Color.GRAY);
viewHolder.io.setEnabled(true);
} else if (status == ChecklistenPunktStatus.NICHT_SELEKTIERT) {
viewHolder.nio.setBackgroundColor(Color.parseColor("#cccccc"));
viewHolder.nio.setEnabled(true);
viewHolder.io.setBackgroundColor(Color.parseColor("#cccccc"));
viewHolder.io.setEnabled(true);
}
v.setTag(viewHolder);
break;
case Util.CHECKLISTE_UEBERSCHRIFT:
v = inflater.inflate(R.layout.pruefung_durchfuehren_list_item_head, null);
viewHolder.headline = (TextView) v.findViewById(R.id.check_headline);
viewHolder.headnummer = (TextView) v.findViewById(R.id.check_headnummer);
v.setTag(viewHolder);
break;
case Util.CHECKLISTE_ZUSATZTEXT:
v = inflater.inflate(R.layout.pruefung_durchfuehren_list_item_text, null);
viewHolder.text = (TextView) v.findViewById(R.id.check_text);
viewHolder.textnummer = (TextView) v.findViewById(R.id.check_textnummer);
v.setTag(viewHolder);
break;
default:
throw new IllegalArgumentException("ViewType " + type + " unbekannt!");
}
} else {
v = convertView;
}
ChecklistenPunkt clp = getItem(position);
ViewHolder viewHolder = (ViewHolder) v.getTag();
if (clp != null) {
switch (type) {
case Util.CHECKLISTE_FRAGE: {
viewHolder.nummer.setText(clp.getNummer());
viewHolder.komponente.setText(clp.getKomponente());
viewHolder.funktion.setText(clp.getFunktion());
viewHolder.kriterium.setText(clp.getKriterium());
viewHolder.erlaeuterung.setText(clp.getErlaeuterung());
ChecklistenPunktStatus status = sparseArray.get(position);
if (status == ChecklistenPunktStatus.IN_ORDNUNG) {
viewHolder.io.setBackgroundColor(Color.GREEN);
viewHolder.io.setEnabled(false);
viewHolder.nio.setBackgroundColor(Color.GRAY);
viewHolder.nio.setEnabled(true);
} else if (status == ChecklistenPunktStatus.NICHT_IN_ORDNUNG) {
viewHolder.nio.setBackgroundColor(Color.RED);
viewHolder.nio.setEnabled(false);
viewHolder.io.setBackgroundColor(Color.GRAY);
viewHolder.io.setEnabled(true);
} else if (status == ChecklistenPunktStatus.NICHT_SELEKTIERT) {
viewHolder.nio.setBackgroundColor(Color.parseColor("#cccccc"));
viewHolder.nio.setEnabled(true);
viewHolder.io.setBackgroundColor(Color.parseColor("#cccccc"));
viewHolder.io.setEnabled(true);
}
break;
}
case Util.CHECKLISTE_UEBERSCHRIFT: {
viewHolder.headline.setText(clp.getHeadline());
viewHolder.headnummer.setText(clp.getNummer());
break;
}
case Util.CHECKLISTE_ZUSATZTEXT: {
viewHolder.text.setText(Html.fromHtml(clp.getZusatz()));
viewHolder.textnummer.setText(clp.getNummer());
break;
}
default:
throw new IllegalArgumentException("ViewType " + type + " unbekannt!");
}
}
return v;
}
public SparseArray<ChecklistenPunktStatus> getSparseArray() {
return sparseArray;
}
static class ViewHolder {
protected TextView nummer;
protected TextView komponente;
protected TextView kriterium;
protected TextView funktion;
protected TextView erlaeuterung;
protected TextView text;
protected TextView textnummer;
protected TextView headline;
protected TextView headnummer;
protected Button io;
protected Button nio;
}
}
EDIT:
When the convertView is null, I create a new View by inflating my layout. Then I create a new ViewHolder, find the different TextViews and Buttons according to the Views viewType and put them into the ViewHolder. After that, I set this ViewHolder as the tag of the View. I distinguish according to the viewType again and set the text and Listeners of the Views inside the ViewHolder. Then I return the view.
When the convertView is not null I reuse the View. I get the ViewHolder with the getTag() method, set the text and Button state according to the model class and return the view at the end of the method.
My problem is that the answering state is correctly saved in the SparseArray, but it is not displayed correctly. When I answer a question in the first rows of my list and then scroll down, answered questions appear at the end of the list. By scrolling up and down I can mess up the answering states completely. But while this is happening, the states in the sparseArray are always correct.
Am I missing something here?
I suppose there is something wrong with the code. When you use the same cell and when the view is not null you should reuse the same holder and not the convertView. Something like that:
ViewHolder viewHolder = new ViewHolder();
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
.
.
.
}
else {
viewHolder = convertView.getTag();
}