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.
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 created an imageviewer app. Its working fine but when I select a gridview item to delete it, it stops working. On selecting the item, delete button appears . On clicking the delete button ,an alert dialog appears asking for confirmation.I want the file to get deleted after cliking the YES button. But it does not happen. Instead it throws an indexoutofbounds exception. How can I delete selected file succesfully ?
PhotosActivity.java
import static com.example.dell_1.myapp3.ImageViewer.ImageGallery.al_images;
public class PhotosActivity extends AppCompatActivity {
int int_position;
private GridView gridView;
GridViewAdapter adapter;
ArrayList<Model_images> al_menu = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_gallery);
final ImageButton button1 = (ImageButton) findViewById(R.id.button1);
final ImageButton button2 = (ImageButton) findViewById(R.id.button2);
final ImageButton button3 = (ImageButton) findViewById(R.id.button3);
final ImageButton button4 = (ImageButton) findViewById(R.id.button4);
final ImageButton button5 = (ImageButton) findViewById(R.id.button5);
button1.setVisibility(View.GONE);
button2.setVisibility(View.GONE);
button3.setVisibility(View.GONE);
button4.setVisibility(View.GONE);
button5.setVisibility(View.GONE);
gridView = (GridView) findViewById(android.R.id.list);
int_position = getIntent().getIntExtra("value", 0);
adapter = new GridViewAdapter(this, al_images, int_position);
gridView.setAdapter(adapter);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String abc = "file://" + al_images.get(int_position).getAl_imagepath().get(position);
Intent i = new Intent(getApplicationContext(), FullImageActivity.class);
i.putExtra("id", position);
i.putExtra("folderPosition", int_position);
i.putExtra("abc", abc);
startActivity(i);
}
});
gridView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, final int position, long id) {
for (int j = 0; j < parent.getChildCount(); j++)
parent.getChildAt(j).setBackgroundColor(Color.TRANSPARENT);
// change the background color of the selected element
view.setBackgroundColor(Color.LTGRAY);
button1.setVisibility(View.VISIBLE);
button2.setVisibility(View.VISIBLE);
button3.setVisibility(View.VISIBLE);
button4.setVisibility(View.VISIBLE);
button5.setVisibility(View.VISIBLE);
button3.setOnClickListener(
new View.OnClickListener() {
public void onClick(View view) {
AlertDialog.Builder builder1 = new AlertDialog.Builder(PhotosActivity.this);
builder1.setMessage("Are you sure you want to delete it ?");
builder1.setCancelable(true);
builder1.setPositiveButton(
"Yes",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
File file = new File( al_menu.get(int_position).getAl_imagepath().get(position));
file.delete();
al_menu.remove(position);
adapter.notifyDataSetChanged();
}
});
builder1.setNegativeButton(
"No",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert11 = builder1.create();
alert11.show();
}
});
return true;
}
});
}
}
GridViewAdapter.java:
public class GridViewAdapter extends ArrayAdapter<Model_images> {
Context context;
ViewHolder viewHolder;
ArrayList<Model_images> al_menu = new ArrayList<>();
int int_position;
public GridViewAdapter(Context context, ArrayList<Model_images> al_menu,int int_position) {
super(context, R.layout.activity_adapter__photos_folder, al_menu);
this.al_menu = al_menu;
this.context = context;
this.int_position = int_position;
}
#Override
public int getCount() {
Log.e("ADAPTER LIST SIZE", al_menu.get(int_position).getAl_imagepath().size() + "");
return al_menu.get(int_position).getAl_imagepath().size();
}
#Override
public int getItemViewType(int position) {
return position;
}
#Override
public int getViewTypeCount() {
if (al_menu.get(int_position).getAl_imagepath().size() > 0) {
return al_menu.get(int_position).getAl_imagepath().size();
} else {
return 1;
}
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
viewHolder = new ViewHolder();
convertView = LayoutInflater.from(getContext()).inflate(R.layout.activity_adapter__photos_folder, parent, false);
viewHolder.tv_foldern = (TextView) convertView.findViewById(R.id.tv_folder);
viewHolder.tv_foldersize = (TextView) convertView.findViewById(R.id.tv_folder2);
viewHolder.iv_image = (ImageView) convertView.findViewById(R.id.iv_image);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.tv_foldern.setVisibility(View.GONE);
viewHolder.tv_foldersize.setVisibility(View.GONE);
Glide.with(context).load("file://" + al_menu.get(int_position).getAl_imagepath().get(position))
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(viewHolder.iv_image);
return convertView;
}
private static class ViewHolder {
TextView tv_foldern, tv_foldersize;
ImageView iv_image;
}
}
LOGCAT :
10-15 11:38:03.449 31844-31844/com.example.dell_1.Myapp3 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.dell_1.Myapp3, PID: 31844
java.lang.IndexOutOfBoundsException: Index: 1, Size: 0
at java.util.ArrayList.get(ArrayList.java:411)
at com.example.dell_1.myapp3.ImageViewer.PhotosActivity$2$1$1.onClick(PhotosActivity.java:87)
at android.support.v7.app.AlertController$ButtonHandler.handleMessage(AlertController.java:161)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
what is al_images ??
you have not initialized al_images
If you want to delete the item for the Grid, you should also have to notify the grid adapter of the change in the data set.
Delete the item from the data set.
Notify the Grid Adapter of the change in data set.
The above behavior needs to be defined in the Adapter's getView() method. While populating the elements after the (if else) block. You should set a tag with every view in order to correctly identify which item you want to delete. Use
ViewHolder.deleteButton.setTag(position);
In this case param will be your delete button, so that after clicking the button, you will know the item whose button is clicked and perform the following function in the getView() method.
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Gets the index of the item to delete
Integer index = (Integer) v.getTag();
// Use the above index to delete item from data set
// Delete your item here
//For e.g: notes.remove(index.intValue());
// Must call this after deletion from the data set
notifyDataSetChanged();
}
});
I have two button increase and decrease and one textview. When I click on increase button the value in the textview is increases and vice versa but when I scroll the listview its get its default value 0. How can I resolve this?
public View getView(final int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.cart_item, parent, false);
viewHolder = new ViewHolder();
viewHolder.mImgItem = (ImageView) convertView.findViewById(R.id.cart_image);
viewHolder.mTvItemName = (TextView) convertView.findViewById(R.id.tv_item_name);
viewHolder.mTvItemPrice = (TextView) convertView.findViewById(R.id.tv_item_price);
viewHolder.mTvNumber = (TextView) convertView.findViewById(R.id.tv_number);
viewHolder.mBtnAdd = (Button) convertView.findViewById(R.id.btn_add);
viewHolder.mBtnMinus = (Button) convertView.findViewById(R.id.btn_sub);
viewHolder.mImgDelete = (ImageView) convertView.findViewById(R.id.img_del);
viewHolder.mUniqueKey = String.valueOf(position);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.mBtnAdd.setTag(viewHolder);
viewHolder.mBtnMinus.setTag(viewHolder);
viewHolder.mTvNumber.setText("0");
viewHolder.mBtnAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ViewHolder tagHolder = (ViewHolder) v.getTag();
int mValue = Integer.parseInt(tagHolder.mTvNumber.getText().toString().trim());
mValue++;
tagHolder.mTvNumber.setText("" + mValue);
});
viewHolder.mBtnMinus.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
ViewHolder tagHolder = (ViewHolder) v.getTag();
int mValue = Integer.parseInt(tagHolder.mTvNumber.getText().toString());
if (mValue > 0) {
mValue--;
tagHolder.mTvNumber.setText("" + mValue);
}
});
convertView.setTag(viewHolder);
PojoCart pojoCart = (PojoCart) getItem(position);
viewHolder.mTvItemName.setText(pojoCart.getmItemName());
viewHolder.mTvItemPrice.setText(pojoCart.getmItemPrice());
return convertView;
}
Save the value to PojoCart class and retrieve value from it every time just as you are getting itemName and itemPrice. So create an integer quantity in PojoCart class and in the adapter's getView method :
PojoCart pojoCart = (PojoCart) getItem(position);
viewHolder.mBtnAdd.setTag(pojoCart);
viewHolder.mBtnMinus.setTag(pojoCart);
if(pojoCart.getQuantity() > 0)
{
viewHolder.mTvNumber.setText(""+pojoCart.getQuantity());
}
else
{
viewHolder.mTvNumber.setText(""+0);
}
viewHolder.mBtnAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
PojoCart pojoCart = (PojoCart) v.getTag();
int mValue = pojoCart.getQuantity();
mValue++;
tagHolder.mTvNumber.setText("" + mValue);
pojoCart.setQuantity(mValue)
notifyDataSetChanged();
};
You have to save value of textview.
As listview recreate views on scroll it takes default
Just take model class and save values by position
Use adapter.notifyDataSetChanged() to update values in listview when data changes
You need to store the number in each list item for example use this function to change the value of the list item's number:
List<Integer> mList = new ArrayList<>(LIST_SIZE);
int changeNumber(int position, int value){
mList.get(position) += value;
return mList.get(position);
}
u can use this function like:
viewHolder.mBtnAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ViewHolder tagHolder = (ViewHolder) v.getTag();
int mValue = Integer.parseInt(tagHolder.mTvNumber.getText().toString().trim());
tagHolder.mTvNumber.setText("" + changeNumber(position,1);
});
viewHolder.mBtnMinus.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
ViewHolder tagHolder = (ViewHolder) v.getTag();
int mValue = Integer.parseInt(tagHolder.mTvNumber.getText().toString());
if (mValue > 0) {
tagHolder.mTvNumber.setText("" + changeNumber(position,-1);
}
});
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();
}
});
}
When i am scrolling ListView position of the item changes.My ListView contain 2 Button and 2 TextView. These 2 Button are initially invisible. when user Long click on item i just set the visibility.Its working but when i scroll the ListView ,it changes the position.Why?
I am setting this visibility and invisibility code inside of my adapter class..
here is my code :::
#Override
public View getView(int position, View convertView, ViewGroup parent) {
holder = new ViewHolder();
if (convertView == null) {
convertView = lInflater.inflate(R.layout.message_row, null);
holder.messageDeleteButton = (Button) convertView
.findViewById(R.id.delete_button);
holder.messageTextView = (TextView) convertView
.findViewById(R.id.message);
holder.timeTextView = (TextView) convertView
.findViewById(R.id.time);
holder.copyMessageButton = (ImageButton) convertView
.findViewById(R.id.copy_bt);
holder.messageDeleteButton
.setOnClickListener(new OnClickListener() {
#Override
public void onClick(final View v) {
System.out.println("Delete clicked");
}
});
convertView.setTag(R.layout.message_row, holder);
} else {
holder = (ViewHolder) convertView.getTag(R.layout.message_row);
}
convertView.setTag(position);
holder.messageDeleteButton.setTag(position);
if (mMessageData.get(position).isVisible())
holder.messageDeleteButton.setVisibility(View.VISIBLE);
else
holder.messageDeleteButton.setVisibility(View.GONE);
holder.messageTextView.setText(mMessageData.get(position)
.getMessage_text());
holder.messageTextView.setTypeface(Typeface.createFromAsset(
mContext.getAssets(), "Existence-Light.ttf"));
holder.timeTextView.setText(mMessageData.get(position)
.getMessage_date());
holder.timeTextView.setTypeface(Typeface.createFromAsset(
mContext.getAssets(), "Existence-Light.ttf"));
convertView.setOnTouchListener(mOnTouchListener);
convertView.setOnClickListener(mOnClickListener);
// convertView.setOnLongClickListener(mLongClick);
return convertView;
}
This is my OnTouchListiner code it will working fine.But when i scroll the ListView the buttons positions will changed..
class MyTouchListener implements OnTouchListener {
#SuppressWarnings("deprecation")
private final GestureDetector gestureDetector = new GestureDetector(
new GestureListener());
#Override
public boolean onTouch(View v, MotionEvent event) {
int touch = 0;
ViewHolder holder = (ViewHolder) v.getTag(R.layout.message_row);
animation = new Animater();
int action = event.getAction();
int position = (Integer) v.getTag();
pos = position;
view = v;
switch (action) {
case MotionEvent.ACTION_DOWN:
action_down_x = (int) event.getX();
Log.d("action", "ACTION_DOWN - ");
touch = 0;
break;
case MotionEvent.ACTION_MOVE:
Log.d("action", "ACTION_MOVE - ");
action_up_x = (int) event.getX();
difference = action_down_x - action_up_x;
calcuateDifference(holder, position);
touch = 1;
break;
case MotionEvent.ACTION_UP:
Log.d("action", "ACTION_UP - ");
// calcuateDifference(holder, position);
action_down_x = 0;
action_up_x = 0;
difference = 0;
// touch = 2;
break;
}
return gestureDetector.onTouchEvent(event);
}
public GestureDetector getGestureDetector() {
return gestureDetector;
}
}
In this gestuer class when i tap on ListView just display one more Button.This also be changed the position
public class GestureListener extends SimpleOnGestureListener{
#SuppressLint("NewApi")
#Override
public void onLongPress(MotionEvent e) {
// TODO Auto-generated method stub
super.onLongPress(e);
final ViewHolder hold = (ViewHolder) view.getTag(R.layout.message_row);
hold.copyMessageButton.setVisibility(View.VISIBLE);
hold.copyMessageButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
System.out.println("hello you click me..");
});
}
}
What is the wrong on my code..Any one please help me...
Android ListView use Adapters to recycle views that's why ListView position changes while scrolling to conserve memory.See the Google I/O presentation given by Romain Guy to understand how adapters work. http://www.youtube.com/watch?v=N6YdwzAvwOA
Also check the below links,
http://strangevikas.wordpress.com/tag/how-adapter-works-in-android-android-and-adapters/
http://www.edureka.in/blog/what-are-adapters-in-android/
You just need to do some modification in your code like:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = new ViewHolder();
if (convertView == null) {
convertView = lInflater.inflate(R.layout.message_row, null);
holder.messageDeleteButton = (Button) convertView
.findViewById(R.id.delete_button);
holder.messageTextView = (TextView) convertView
.findViewById(R.id.message);
holder.timeTextView = (TextView) convertView
.findViewById(R.id.time);
holder.copyMessageButton = (ImageButton) convertView
.findViewById(R.id.copy_bt);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.messageDeleteButton.setTag(mMessageData.get(position));
holder.messageDeleteButton
.setOnClickListener(new OnClickListener() {
#Override
public void onClick(final View v) {
// message data can be retrieved here like
MessageData mData = (MessageData) v.getTag();
System.out.println("Delete clicked");
}
});
if (mMessageData.get(position).isVisible())
holder.messageDeleteButton.setVisibility(View.VISIBLE);
else
holder.messageDeleteButton.setVisibility(View.GONE);
holder.messageTextView.setText(mMessageData.get(position)
.getMessage_text());
holder.messageTextView.setTypeface(Typeface.createFromAsset(
mContext.getAssets(), "Existence-Light.ttf"));
holder.timeTextView.setText(mMessageData.get(position)
.getMessage_date());
holder.timeTextView.setTypeface(Typeface.createFromAsset(
mContext.getAssets(), "Existence-Light.ttf"));
return convertView;
}