Listview postion not working properly - android

I have list view. I want to change color of clicked row. But only 0,1 and 2 indexes are correctly colored others are not working properly likewise if i clicked on 4th row the 5th one row color changes and sometimes if i clicked on 7th row then none of row is colored. Please Help
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,final int position, long id) {
for (int i = 0; i < lv.getChildCount(); i++) {
if(position == i ){
lv.getChildAt(i).setBackgroundColor(Color.BLUE);
}else{
lv.getChildAt(i).setBackgroundColor(Color.TRANSPARENT);
}
}
public abstract class CustomAdapter extends BaseAdapter implements SeekBar.OnSeekBarChangeListener {
Context context;
ArrayList<HashMap<String, String>> countryList;
ArrayList<HashMap<String, String>> mStringFilterList;
LayoutInflater inflter;
public ImageView img2,img3;
Handler mHandler = new Handler();
SeekBar songProgressBar;
SelfUpdatingSeekbar self;
public boolean isStarted = true;
public static final int UPDATE_FREQUENCY = 500;
public static final int STEP_VALUE = 4000;
public final Handler handler = new Handler();
public final Runnable updatePositionRunnable = new Runnable() {
public void run() {
updatePosition();
}
};
public CustomAdapter(Context applicationContext, ArrayList<HashMap<String, String>> countryList) {
this.context = applicationContext;
this.countryList = countryList;
mStringFilterList = countryList;
inflter = (LayoutInflater.from(applicationContext));
}
#Override
public int getCount() {
return countryList.size();
}
public void updateData(ArrayList<HashMap<String, String>> countryList) {
this.countryList = countryList;
notifyDataSetChanged();
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(final int position, View view, ViewGroup viewGroup) {
view = inflter.inflate(R.layout.list_itemss, null);
view.setTag(position);
String hello = String.valueOf(countryList.get(position));
String s = hello;
int s1 = s.lastIndexOf("=");
int s2 = s.lastIndexOf("}");
strSub = s.substring(s1+1,s2/*s.lastIndexOf("=")*/);
Log.d("Hello",hello);
String henno1 = String.valueOf(hello.length());
Log.d("hellya",strSub);
TextView country = (TextView) view.findViewById(R.id.textView);
country.setText(strSub);
uniqueItemIdCount = countryList.size();
Log.d("PrintIdss", String.valueOf(uniqueItemIdCount));
ImageView twitt = (ImageView)view.findViewById(R.id.button5);
twitt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
TweetComposer.Builder builder = new TweetComposer.Builder(context)
.text(strSub);
builder.show();
}
});
ImageView fb = (ImageView)view.findViewById(R.id.button6);
fb.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
ShareLinkContent linkContent = new ShareLinkContent.Builder()
.setContentTitle(strSub)
.setContentDescription(
"Top Hollywood Songs")
.setContentUrl(Uri.parse("http://www.moremovies.com/"))
.build();
shareDialog.show(linkContent);
}
});
songProgressBar = (SeekBar) view.findViewById(R.id.songProgressBar);
songProgressBar.setOnSeekBarChangeListener(this);
songCurrentDurationLabel = (TextView)view.findViewById(R.id.songCurrentDurationLabel);
songTotalDurationLabel = (TextView)view.findViewById(R.id.songTotalDurationLabel);
img2 = (ImageView)view.findViewById(R.id.button3);
img2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int songIndex = position;
String hellos = String.valueOf(countryList.get(songIndex));
int s1 = hellos.lastIndexOf("=");
int s2 = hellos.lastIndexOf("}");
String strSubs = hellos.substring(s1+1,s2/*s.lastIndexOf("=")*/);
selelctedFile.setText(strSubs);
currentSongIndex=songIndex;
playSong(currentSongIndex);
}
});
}

You have to manage the position and the background of yourself because in your adapter as you are reusing the cell. Kindly check your adapter you will get it.
And to achieve what you want. You have to update your adapter and implement the click listener in the Adapter view.

Try to subtract the position of your listview:
for (int i = 0; i < lv.getChildCount(); i++) {
if(position - lv.getFirstVisiblePosition() == i ){ //<-Here
lv.getChildAt(i).setBackgroundColor(Color.BLUE);
}else{
lv.getChildAt(i).setBackgroundColor(Color.TRANSPARENT);
}
}

You need to implement the two background options, because the adapter will reuse your layout.
So you need to keep track of the selected items (not layouts), as i see you are using a HashMap to populate your adapter so, create a List with the selected positions and when you are populating your adapter do something like :
//Globals Variables
List<int> SelectedList = new ArrayList<>();
//On select event
SelectedList.add(position);
//On deselect event
SelectedList.remove(position);
//On get view
if(SelectedList.contains(position){
// Background selected
}else{
// Explicit set the background to the default
}

If you want to start with play buttons and on click change to pause the one clicked and all others back to play then inside your adapter where you initialize the play/pause button do :
playPause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,final int position, long id) {
for (int i = 0; i < lv.getChildCount(); i++) {
Button PlayPause = v.findViewById(R.id.play_pause_button)
ButtonPlayPause.setImageResource("play resource")
}
playPause.setImageResource("pause resource")
}
}
}
});
Code may have some syntax errors but you get the idea.

Related

how to control listview to reload.

I face a problem in list view. In my list view have edit text and text view. When i scroll the list my data that is entered in text view has lost the value and show the default value. i have two button in list view i increase the quantity and scroll the list for next product when i come back text view lost the value and show default value 1 . And when i open keyboard for enter data then same issue . please help me.
And its my code
Custom Adapter
private List<ShowProducts> listShowProducts;
private Context context;
private int resource;
private String condition;
String uri;
private static final String TAG = "CustomAdapter";
int i = 0;
float total;
ListView listView;
TextView tvTotal;
float sum = 0;
public CustomAdapter(#NonNull Context context, #LayoutRes int resource, List<ShowProducts> objects) {
super(context, resource, objects);
this.context = context;
this.resource = resource;
this.listShowProducts = objects;
}
#Override
public int getCount() {
return super.getCount();
}
#Nullable
#Override
public Object getItem(int position) {
return super.getItem(position);
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
View view = LayoutInflater.from(context).inflate(resource, parent, false);
{
final ShowProducts showProducts = listShowProducts.get(position);
ImageView imageView = (ImageView) view.findViewById(R.id.imageViewOfSelecteditem);
ImageView plus = (ImageView) view.findViewById(R.id.imageviewPlus);
ImageView minus = (ImageView) view.findViewById(R.id.imageviewminus);
TextView tvSetNameOfSeletedItem = (TextView) view.findViewById(R.id.tvSetNameOfSeletedItem);
TextView tvSetSizeOfSeletedItem = (TextView) view.findViewById(R.id.tvSetSizeOfSeletedItem);
TextView tvSetPriceOfSeletedItem = (TextView) view.findViewById(R.id.tvSetPriceOfSeletedItem);
final TextView tvQunatitySetOfSelectedItem = (TextView) view.findViewById(R.id.tvQunatitySetOfSelectedItem);
for (int a = 0; a < 10; a++) {
Log.d(TAG, "onnnnView: ");
}
Log.d(TAG, "getView: +++++");
tvSetNameOfSeletedItem.setText(showProducts.getProduct_name().toString());
tvSetSizeOfSeletedItem.setText(showProducts.getSize_name());
tvSetPriceOfSeletedItem.setText(String.valueOf(showProducts.getSize_price()).toString());
uri = showProducts.getProduct_photo().toString();
Picasso.with(context).load(uri).into(imageView);
plus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int a = Integer.parseInt(tvQunatitySetOfSelectedItem.getText().toString());
a++;
Log.d(TAG, "getView: ");
if (a <= showProducts.getSize_quantity()) {
tvQunatitySetOfSelectedItem.setText(String.valueOf(a).toString());
tvTotal = (TextView) ((Activity) context).findViewById(R.id.tvTotalShow);
float price = Float.parseFloat(tvTotal.getText().toString());
sum = price + showProducts.getSize_price();
tvTotal.setText(String.valueOf(sum));
}
}
});
minus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int a = Integer.parseInt(tvQunatitySetOfSelectedItem.getText().toString());
a--;
if (a > 0)
{
tvQunatitySetOfSelectedItem.setText(String.valueOf(a).toString());
tvTotal = (TextView) ((Activity) context).findViewById(R.id.tvTotalShow);
float price = Float.parseFloat(tvTotal.getText().toString());
sum = price - showProducts.getSize_price();
tvTotal.setText(String.valueOf(sum));
}
}
});
}
return view;
}
And activity code
public class SelectedProductFromShopingCartShow extends AppCompatActivity {
ArrayList<ShowProducts> arrayList = new ArrayList<>();
String condition = "SelectedItemsFromShoppingCart";
CustomAdapter customAdapter;
ListView listView;
TextView tvTotal;
EditText etDiscount;
int total;
float sum = 0;
Button discount;
private static final String TAG = "SelectedProductFromShop";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_selected_product_from_shoping_cart_show);
listView = (ListView) findViewById(R.id.listViewSelectedItemsOfShopingCart);
tvTotal = (TextView) findViewById(R.id.tvTotalShow);
etDiscount = (EditText) findViewById(R.id.etDiscount);
arrayList = (ArrayList<ShowProducts>) getIntent().getSerializableExtra("selectedList");
ShowProducts showProducts = arrayList.get(0);
Log.d(TAG, "onnnnCreate: " + showProducts.getProduct_name());
customAdapter = new CustomAdapter(SelectedProductFromShopingCartShow.this, R.layout.show_selected_item_of_shopingcart, condition, arrayList);
listView.setAdapter(customAdapter);
getTotalListView();
Log.d(TAG, "onnnnCreate: Before inner class");
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, final int position, long id) {
AlertDialog.Builder builder = new AlertDialog.Builder(SelectedProductFromShopingCartShow.this);
builder.setTitle("Delete this product");
builder.setMessage("Are you sure you want to delete it?");
builder.setCancelable(true);
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
arrayList.remove(position);
customAdapter.notifyDataSetChanged();
Toast.makeText(SelectedProductFromShopingCartShow.this, "item deleted", Toast.LENGTH_SHORT).show();
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.show();
return true;
}
});
}
public void getTotalListView() {
sum = 0;
for (int i = 0; i < arrayList.size(); i++) {
ShowProducts showProducts = arrayList.get(i);
sum = sum + showProducts.getSize_price();
tvTotal.setText(String.valueOf(sum));
}
}
And watch this video for understand problems
https://youtu.be/WAjtRkI5dl4
You need to follow viewholder pattern. It will resolve your issue. You can check it here https://developer.android.com/training/improving-layouts/smooth-scrolling.html
The only place you're keeping count is in the view. You should make your count a field in the list item ShowProducts and create a getter & setter. For example, in the plus onClickListener, instead of
int a = Integer.parseInt(tvQunatitySetOfSelectedItem.getText().toString());
a++;
You'll have
// for example, in the `plus` listener
int a = showProducts.getCount();
a++;
showProducts.setCount(a);
And don't forget
notifyDataSetChanged();

How to modify only one row at a time while using Customized ListView

I have used Customized ListView And not ExtendedListView. i have taken relative layout in order to show it as sub_list. By default i have set the visibilty of this sub_list relative layout as GONE. And on the click of any listItem that relative layout(by default set as gone) will appear on the screen respectively. But When I click on any of the rows the sub_list appear for each row simultaneously. What i want is that it should be shown only for one row at a time. I have already checked this similar [question]: How to modify only one row at a time in Listview? and modified my code but still i am unable to achieve my goal.
Here is my pieace of code:
public class CustomAdapter extends BaseAdapter {
Activity context;
ArrayList<String> s_date,c_number,d_ration,s_time,download_path,a_number,a_name,dt_number;
int flag=0,temp=1,position;
String mUrl;
int posview;
private int selectedIndex;
CustomAdapter(Activity context, ArrayList<String> start_date, ArrayList<String> caller_number, ArrayList<String> duration,ArrayList<String> start_time, ArrayList<String> download_path, ArrayList<String> agent_number, ArrayList<String> agent_name,ArrayList<String> dt_num)
{
this.context=context;
this.s_date=start_date;
this.c_number=caller_number;
this.d_ration=duration;
this.s_time=start_time;
this.download_path=download_path;
this.a_number=agent_number;
this.a_name=agent_name;
this.dt_number=dt_num;
selectedIndex = -1;
}
public void setSelectedIndex(int ind)
{
selectedIndex = ind;
notifyDataSetChanged();
}
#Override
public int getCount() {
return s_date.size();
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int position) {
return position;
}
public View getView(final int pos, final View v, ViewGroup g)
{
//LayoutInflater l=context.getLayoutInflater();
//View rowView=l.inflate(R.layout.log_layout,null,true);
posview=pos;
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View row = inflater.inflate(R.layout.list_item, g, false);
TextView start_date = (TextView) row.findViewById(R.id.start_date);
start_date.setText(s_date.get(pos));
TextView caller_number = (TextView) row.findViewById(R.id.caller_number);
caller_number.setText(c_number.get(pos));
TextView duration = (TextView) row.findViewById(R.id.duration);
duration.setText(d_ration.get(pos));
TextView start_time = (TextView) row.findViewById(R.id.start_time);
start_time.setText(s_time.get(pos));
TextView agent_name = (TextView) row.findViewById(R.id.agent_name);
agent_name.setText(a_name.get(pos));
TextView agent_number = (TextView) row.findViewById(R.id.agent_number);
agent_number.setText(a_number.get(pos));
TextView dt_numb=(TextView)row.findViewById(R.id.dt_number);
dt_numb.setText("MHL No. -"+dt_number.get(pos));
RelativeLayout r = (RelativeLayout)row.findViewById(R.id.sub_layout);
r.setVisibility(position == posview ? View.VISIBLE : View.GONE);
row.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
posview=pos;
notifyDataSetChanged();
}
});
return row;
}
}
Previously my code was:
row.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//setSelectedIndex(view.getId());
RelativeLayout sub_list = (RelativeLayout) row.findViewById(R.id.sub_layout);
sub_list.setVisibility(View.VISIBLE);
//notifyDataSetChanged();
}
});
I am getting all the data dynamically. This is how i'm using the adapter in MainActivity:
CustomAdapter a=new CustomAdapter(MainScreen.this,start_date,caller_number,duration,start_time,download_path,agent_number,agent_name,dt_number);
data_list.setAdapter(a);
In this start_date caller_number etc are arraylist.This is how i'm parsing data in MainActivity.
JSONObject responseObject = new JSONObject(response);
JSONObject callLog = responseObject.getJSONObject("call_log");
Iterator<String> phoneNumbers = callLog.keys();
while (phoneNumbers.hasNext()) {
String number = phoneNumbers.next();
// Log.v("string number",number);
JSONObject numberLog = callLog.getJSONObject(number);
Iterator<String> callEntries = numberLog.keys();
while (callEntries.hasNext()) {
String entry = callEntries.next();
//Log.v("unique keys are",entry);
JSONObject entryObject = numberLog.getJSONObject(entry);
jsonArray.put(entryObject.getString("start_date"));
jsonArray.put(entryObject.getString("start_time"));
jsonArray.put(entryObject.getString("end_date"));
jsonArray.put(entryObject.getString("end_time"));
jsonArray.put(entryObject.getString("recording_path"));
String startDate = entryObject.getString("start_date");
start_date.add(startDate);
String startTime = entryObject.getString("start_time");
start_time.add(startTime);
String endDate = entryObject.getString("end_date");
String endTime = entryObject.getString("end_time");
String call_sdate = entryObject.getString("call_sdate");
String call_edate = entryObject.getString("call_edate");
String call_type = entryObject.getString("call_type");
String caller = entryObject.getString("caller");
caller_number.add(caller);
String duartion = entryObject.getString("duartion");
String call_duartion = entryObject.getString("call_duartion");
duration.add(call_duartion);
String dtmf = entryObject.getString("dtmf");
String dt_num = entryObject.getString("dt_number");
dt_number.add((dt_num));
String recording_path = entryObject.getString("recording_path");
download_path.add(recording_path);
String agent_mobile = entryObject.getString("agent_mobile");
agent_number.add(agent_mobile);
String a_name = entryObject.getString("agent_name");
agent_name.add(a_name);
Create two variables :
Map<Integer, View> lastExpanded = new HashMap<>();
int lastExpandedPosition =-1;
Create a function in your adapter :
private void expand(int i, View layout){
if(!lastExpanded.containsKey(i)){
layout.setVisibility(View.VISIBLE);
lastExpanded.put(i, layout);
if(lastExpanded.containsKey(lastExpandedPosition)){
expand(lastExpandedPosition, lastExpanded.get(lastExpandedPosition));
}
lastExpanded.remove(lastExpandedPosition);
lastExpandedPosition = i;
lastExpanded.put(lastExpandedPosition, layout);
}else{
layout.setVisibility(View.GONE);
lastExpandedPosition = -1;
lastExpanded.remove(i);
}
}
now,
final RelativeLayout layout = (RelativeLayout) row.findViewById(R.id.b);
layout.setVisibility(View.GONE);
row.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
expand(i, layout);
}
});
You can acheive this easily with expandable listview and your adapter class should extend BaseExpandableListAdapter
in activity
private int lastExpandedPosition = -1;
expListView.setOnGroupClickListener(new OnGroupClickListener() {
#Override
public boolean onGroupClick(ExpandableListView parent, View v,
final int groupPosition, long id) {
// TODO Auto-generated method stub
if (parent.isGroupExpanded(groupPosition)) {
expListView
.collapseGroup(lastExpandedPosition);
} else {
expListView.expandGroup(groupPosition);
}
return true;
}
});
expListView.setOnGroupExpandListener(new OnGroupExpandListener() {
#Override
public void onGroupExpand(int groupPosition) {
// TODO Auto-generated method stub
if (lastExpandedPosition != -1
&& groupPosition != lastExpandedPosition) {
expListView
.collapseGroup(lastExpandedPosition);
}
lastExpandedPosition = groupPosition;
}
});
You have to use ArrayList which contents as your data while you click on the item.
public class DataModel{
private String s_date,c_number,d_ration,s_time,download_path,a_number,a_name,dt_number;
private boolean isChildVisible;
..... create it's setter and getter methods.
}
when itemclick is called that time you should update the flag of isChildVisible for that position.
public void setSelectedIndex(int ind)
{
arrayListDataModel.get(ind).setIsChildVisible(true);
notifyDataSetChanged();
}
In your getview method :
public View getView(final int pos, final View v, ViewGroup g)
{
----your initialization code.
RelativeLayout r = (RelativeLayout)row.findViewById(R.id.sub_layout);
r.setVisibility(arrayListDataModel.get(pos).isChildVisible() ? View.VISIBLE : View.GONE);
row.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
setSelectedIndex(pos);
}
});
return row;
}
parse the data with below code :
final ArrayList<DataModel> dataModelList = new ArrayList<>();
while (callEntries.hasNext()) {
DataModel dataModel = new DataModel();
String entry = callEntries.next();
//Log.v("unique keys are",entry);
JSONObject entryObject = numberLog.getJSONObject(entry);
jsonArray.put(entryObject.getString("start_date"));
jsonArray.put(entryObject.getString("start_time"));
jsonArray.put(entryObject.getString("end_date"));
jsonArray.put(entryObject.getString("end_time"));
jsonArray.put(entryObject.getString("recording_path"));
String startDate = entryObject.getString("start_date");
dataModel.setStartDate(startDate);
String startTime = entryObject.getString("start_time");
dataModel.setStartTime(startTime);
...... same as above for others fields
dataModelList.add(dataModel);
}

How to get the position of Item on Click in Android

Hello Everyone!!
I am making a sample shopping cart in which i need to get the position of item clicked and get the image displayed on the page on selecting the image from the shopping cart..But here i am getting image of first item only no matter i have clicked another..it is always showing first image of the list...
Here is my code for ProductAdapter.java
public class ProductAdapter extends BaseAdapter {
private List<Product> mProductList;
private LayoutInflater mInflater;
private boolean mShowQuantity;
public ProductAdapter(List<Product> list, LayoutInflater inflater, boolean showQuantity) {
mProductList = list;
mInflater = inflater;
mShowQuantity = showQuantity;
}
#Override
public int getCount() {
return mProductList.size();
}
#Override
public Object getItem(int position) {
return mProductList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewItem item;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item, null);
item = new ViewItem();
item.productImageView = (ImageView) convertView
.findViewById(R.id.ImageViewItem);
item.productTitle = (TextView) convertView
.findViewById(R.id.TextViewItem);
item.productQuantity = (TextView) convertView
.findViewById(R.id.textViewQuantity);
convertView.setTag(item);
} else {
item = (ViewItem) convertView.getTag();
}
Product curProduct = mProductList.get(position);
item.productImageView.setImageDrawable(curProduct.productImage);
item.productTitle.setText(curProduct.title);
// Show the quantity in the cart or not
if (mShowQuantity) {
item.productQuantity.setText("Quantity: "
+ ShoppingCartHelper.getProductQuantity(curProduct));
} else {
// Hid the view
item.productQuantity.setVisibility(View.GONE);
}
return convertView;
}
private class ViewItem {
ImageView productImageView;
TextView productTitle;
TextView productQuantity;
}}
And Here is my shoppingcart file
public class ShoppingCartActivity extends Activity {
private List<Product> mCartList;
private ProductAdapter mProductAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.shoppingcart);
mCartList = ShoppingCartHelper.getCartList();
// Make sure to clear the selections
for (int i = 0; i < mCartList.size(); i++) {
mCartList.get(i).selected = false;
}
// Create the list
final ListView listViewCatalog = (ListView) findViewById(R.id.ListViewCatalog);
mProductAdapter = new ProductAdapter(mCartList, getLayoutInflater(),
true);
listViewCatalog.setAdapter(mProductAdapter);
listViewCatalog.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Intent productDetailsIntent = new Intent(getBaseContext(),
ProductDetailsActivity.class);
productDetailsIntent.putExtra(ShoppingCartHelper.PRODUCT_INDEX,
position);
startActivity(productDetailsIntent);
}
});
}
#Override
protected void onResume() {
super.onResume();
// Refresh the data
if (mProductAdapter != null) {
mProductAdapter.notifyDataSetChanged();
}
double subTotal = 0;
for (Product p : mCartList) {
int quantity = ShoppingCartHelper.getProductQuantity(p);
subTotal += p.price * quantity;
}
TextView productPriceTextView = (TextView) findViewById(R.id.TextViewSubtotal);
productPriceTextView.setText("Subtotal: $" + subTotal);
}
}
ProductActivity.java
public class CatalogActivity extends Activity {
private List<Product> mProductList;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.catalog);
// Obtain a reference to the product catalog
mProductList = ShoppingCartHelper.getCatalog(getResources());
// Create the list
ListView listViewCatalog = (ListView) findViewById(R.id.ListViewCatalog);
listViewCatalog.setAdapter(new ProductAdapter(mProductList, getLayoutInflater(), false));
listViewCatalog.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
Intent productDetailsIntent = new Intent(getBaseContext(),ProductDetailsActivity.class);
productDetailsIntent.putExtra(ShoppingCartHelper.PRODUCT_INDEX, position);
startActivity(productDetailsIntent);
}
});
Button viewShoppingCart = (Button) findViewById(R.id.ButtonViewCart);
viewShoppingCart.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent viewShoppingCartIntent = new Intent(getBaseContext(), ShoppingCartActivity.class);
startActivity(viewShoppingCartIntent);
}
});
}
}
Code for ProductDetailsActivity.java
public class ProductDetailsActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.productdetails);
List<Product> catalog = ShoppingCartHelper.getCatalog(getResources());
int productIndex = getIntent().getExtras().getInt(
ShoppingCartHelper.PRODUCT_INDEX);
final Product selectedProduct = catalog.get(productIndex);
// Set the proper image and text
ImageView productImageView = (ImageView) findViewById(R.id.ImageViewProduct);
productImageView.setImageDrawable(selectedProduct.productImage);
TextView productTitleTextView = (TextView) findViewById(R.id.TextViewProductTitle);
productTitleTextView.setText(selectedProduct.title);
TextView productDetailsTextView = (TextView) findViewById(R.id.TextViewProductDetails);
productDetailsTextView.setText(selectedProduct.description);
TextView productPriceTextView = (TextView) findViewById(R.id.TextViewProductPrice);
productPriceTextView.setText("$" + selectedProduct.price);
// Update the current quantity in the cart
TextView textViewCurrentQuantity = (TextView) findViewById(R.id.textViewCurrentlyInCart);
textViewCurrentQuantity.setText("Currently in Cart: "
+ ShoppingCartHelper.getProductQuantity(selectedProduct));
// Save a reference to the quantity edit text
final EditText editTextQuantity = (EditText) findViewById(R.id.editTextQuantity);
Button addToCartButton = (Button) findViewById(R.id.ButtonAddToCart);
addToCartButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// Check to see that a valid quantity was entered
int quantity = 0;
try {
quantity = Integer.parseInt(editTextQuantity.getText()
.toString());
if (quantity < 0) {
Toast.makeText(getBaseContext(),
"Please enter a quantity of 0 or higher",
Toast.LENGTH_SHORT).show();
return;
}
} catch (Exception e) {
Toast.makeText(getBaseContext(),
"Please enter a numeric quantity",
Toast.LENGTH_SHORT).show();
return;
}
// If we make it here, a valid quantity was entered
ShoppingCartHelper.setQuantity(selectedProduct, quantity);
// Close the activity
finish();
}
});
}
Plz guys Any help will be highly appreciated.
Thanx in advance..
The int position in onItemClick gives the position of the clicked item in the array/list you gave to the adapter.
You can also do getItemAtPosition(); on your listview, if you don't have an easy handle on your original list.
add this code to your Project :
mProductList.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick(AdapterView<?> parent,
View v, int position, long id)
{
int h = parent.getPositionForView(v);
Toast.makeText(getBaseContext(),
"pic" + (position + 1) + " selected" + h,
Toast.LENGTH_SHORT).show();
}
});
Just geussig that you have a problematic code where you are reading the index value. Following is the sample code for writing and reading int extra:
To put int value:
productDetailsIntent.putExtra(ShoppingCartHelper.PRODUCT_INDEX,
position);
Following code should be used to read this value in another Activity
int index = getIntent().getExtras().getInt(ShoppingCartHelper.PRODUCT_INDEX);
Hope it helps...

ListView does not render all items until interacted with

I have a very strange problem while using my ListView.
Only a part of my adapter items are renderd in the listview on screen but when I interact with the listview (ie tries to scroll it) all items are renderd properly.
This fenonemon only occurs if i have less items than the screen can show. Take a look at these screenshots below.
Before interaction:
After interaction:
Source code of activity where adding items:
String[] jRests = getResources().getStringArray(R.array.j_restaurants);
String[] lRests = getResources().getStringArray(R.array.l_restaurants);
items = new ArrayList<Object>();
items.add(getString(R.string.campus_j));
for(String item : jRests){
String[] val = item.split(",,,");
items.add(new FoodSectionListItem(new Restaurant(val[0], val[1], val[2], "")));
}
items.add(getString(R.string.campus_l));
for(String item : lRests){
String[] val = item.split(",,,");
items.add(new FoodSectionListItem(new Restaurant(val[0], val[1], val[2], "")));
}
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
adapter = new BaseSectionAdapter(this, R.layout.list_item_fragment_header);
if(!isTabletView()){
adapter.setSelectedItem(-1);
}
adapter.setItems(items);
Code of adapter:
public class BaseSectionAdapter extends AmazingAdapter {
private LayoutInflater inflater;
private int selectedItem = 0;
private List<Object> items;
private List<SectionItem> sections = new ArrayList<SectionItem>(10);
private List<Class> itemTypes = new ArrayList<Class>();
private List<Integer> sectionPositions = new ArrayList<Integer>();
private int listHeaderLayoutId;
private View headerView;
public static interface ISectionListItem {
public void setProps(View convertView, int position, int selectedItem);
public View getLayout(LayoutInflater inflater);
}
private class SectionItem implements Serializable {
private static final long serialVersionUID = -8930010937740160935L;
String text;
int position;
public SectionItem(String text, int position) {
this.text = text;
this.position = position;
}
}
public BaseSectionAdapter(Context context, int listHeaderLayoutId) {
this.listHeaderLayoutId = listHeaderLayoutId;
init(context);
}
public BaseSectionAdapter(Context context, int listHeaderLayoutId, List<Object> listItems) {
this.listHeaderLayoutId = listHeaderLayoutId;
init(context);
initListItems(listItems);
}
private void init(Context context) {
inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public void setSelectedItem(int position) {
selectedItem = position;
}
// public List<ListItem> getItems() {
// return items;
// }
private void initListItems(List<Object> itemList) {
int curSection = -1;
//int curPosition = 0;
//curSection = 0;
this.items = itemList;
itemTypes.clear();
sections.clear();
sectionPositions.clear();
int listSize = itemList.size();
for(int i = 0; i < listSize; i++){
Object currentItem = items.get(i);
if(currentItem instanceof String){
sections.add(new SectionItem((String) currentItem,i));
curSection++;
}
if(!itemTypes.contains(currentItem.getClass())){
itemTypes.add(currentItem.getClass());
}
sectionPositions.add(curSection);
}
Log.d("test", "No of items = "+items.size());
Log.d("test", "No of itemtypes = "+itemTypes.size());
Log.d("test", "View type count = "+getViewTypeCount());
}
public void setItems(List<Object> itemList) {
initListItems(itemList);
}
public int getCount() {
return items==null?0:items.size();
}
#Override
public int getViewTypeCount(){
return (itemTypes.size() == 0)?1:itemTypes.size();
}
#Override
public int getItemViewType(int position){
return itemTypes.indexOf(items.get(position).getClass());
}
#Override
public boolean isEnabled(int position){
return !(items.get(position) instanceof String || items.get(position) instanceof EmptySectionListItem);
}
#Override
public Object getItem(int position) {
return items.get(position);
}
public long getItemId(int position) {
return position;
}
#Override
protected void onNextPageRequested(int page) {
// TODO Auto-generated method stub
}
#Override
protected void bindSectionHeader(View view, int position,
boolean displaySectionHeader) {
// TextView lSectionTitle = (TextView) view
// .findViewById(R.id.txt_list_header);
// if (displaySectionHeader) {
// lSectionTitle.setVisibility(View.VISIBLE);
// lSectionTitle
// .setText(getSections()[getSectionForPosition(position)]);
// } else {
// lSectionTitle.setVisibility(View.GONE);
// }
}
#Override
public View getAmazingView(int position, View convertView, ViewGroup parent) {
Object curItemObject = items.get(position);
boolean isHeader = (curItemObject instanceof String);
if(convertView == null){
if(isHeader && headerView != null){
convertView = headerView;
}else if(isHeader){
convertView = inflater.inflate(listHeaderLayoutId, null);
headerView = convertView;
}else{
convertView = ((ISectionListItem) curItemObject).getLayout(inflater);
}
}
if(isHeader){
TextView header = ((TextView)convertView.findViewById(R.id.txt_list_header));
header.setText((String)curItemObject);
}else{
((ISectionListItem)curItemObject).setProps(convertView, position, selectedItem);
}
return convertView;
}
#Override
public void configurePinnedHeader(View header, int position, int alpha) {
TextView textView = ((TextView)header.findViewById(R.id.txt_list_header));
textView.setText(getSections()[getSectionForPosition(position)]);
}
#Override
public int getPositionForSection(int section) {
if(section >= sections.size()){
return 0;
}
return sections.get(section).position;
}
#Override
public int getSectionForPosition(int position) {
return sectionPositions.get(position);
}
#Override
public String[] getSections() {
String[] res = new String[sections.size()];
for (int i = 0; i < res.length; i++) {
res[i] = sections.get(i).text;
}
return res;
}
}
Code of layout:
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.HORIZONTAL);
FrameLayout listLayout = new FrameLayout(this);
LinearLayout.LayoutParams listParams = new LinearLayout.LayoutParams(0, FrameLayout.LayoutParams.MATCH_PARENT);
listParams.weight = 1;
listLayout.setId(LIST_FRAGMENT_VIEW_ID);
FrameLayout detailLayout = new FrameLayout(this);
LinearLayout.LayoutParams detailParams = new LinearLayout.LayoutParams(0, FrameLayout.LayoutParams.MATCH_PARENT);
detailParams.weight = 2;
detailLayout.setId(DETAIL_FRAGMENT_VIEW_ID);
layout.addView(listLayout, listParams);
layout.addView(detailLayout, detailParams);
if(savedInstanceState == null){
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(listLayout.getId(), (Fragment) listFragment, TWO_PANEL_LIST_FRAGMENT_TAG);
ft.add(detailLayout.getId(), detailFragment);
ft.commit();
}
setContentView(layout);
try calling notifyDataSetChanged() in runOnUIThread() method like I have shown below and it will work like a charm. :)
runOnUiThread(new Runnable() {
#Override
public void run() {
messageAdapter.notifyDataSetChanged();
}
});
i dont know what causes the problem, but if you don't find a logical solution to it you could try something like this:
trigger an onTouchEvent() programmatically whenever you launch the ListView.
scroll down and back up programmatically as soon as the ListView is launched.
etc..
Add ListView widget to layout.xml and add content of list to that. Do not use FrameLayout as it probably is the cause of the problem. It is updating content after touch so the Layout it is on is no implementing the correct onCreate() setup as the ListView widget has.
Are you calling the method notifyDataSetChanged() on your adapter after adding new items? This causes the listview to refresh its view when the underlying dataset is changed.
If it still doesn't work, try notifyDataSetInvalidated() that causes the listview to redraw completely.
Solved it!!!
Problem was with the adapter trying to reuse the same section item. Not good!!!
Changed it to inflate the section item each time we hit a section!

Why is my BaseAdapter class not incrementing the position in getView?

Edit: My issue seems like BaseAdapter just wont post more than 1 Spinner. If I change the array's size to 0, it wont put anything, but anything more than 1 is truncating it. It never passes position 0 from getView() and it never shwows anymore than 1. I have been at it for hours. Is there a reason for this?
I am having an issue with adding Spinners dynamically in a ListView using a BaseAdapter. I tried it before as a test to make sure it could be done correctly in a test class, and it iterates the positions correctly. But now I am doing it again and its failing. What I mean by failing is instead of getView() creating the new Spinner, it never leaves position 0. It still runs. Just never adds more Spinners.
This is my code:
Main Adapter code
public class RemindersAdapter extends BaseAdapter{
Spinner[] shownReminders = new Spinner[1];
TextView[] removeReminders = new TextView[1];
String[] reminders = new String[1]; //this hlds the values of the coresponding spinner
RemindersAdapter mAdapter;
#Override
public int getCount() {
return shownReminders.length;
}
#Override
public Object getItem(int position) {
return shownReminders[position];
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View view, ViewGroup parent) {
Log.d("TAG", "A NEW SPINNER AND TEXTVIEW IS CREATED HERE WITH POSITION"+position);
if(view == null) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
view = inflater.inflate(R.layout.reminder_spinner, parent, false);
}
Spinner reminderSpinner = (Spinner)view.findViewById(R.id.reminder_spinner);
reminderSpinner.setTag(String.valueOf(position));
ArrayAdapter<CharSequence> reminderAdapter = ArrayAdapter.createFromResource(
parent.getContext(), R.array.reminders_array, android.R.layout.simple_spinner_item);
reminderAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
reminderSpinner.setAdapter(reminderAdapter);
reminderSpinner.setOnItemSelectedListener(new MyOnReminderSelectedListener());
shownReminders[position] = reminderSpinner;
TextView remove = (TextView)view.findViewById(R.id.remove_reminder);
remove.setTag(String.valueOf(position));
removeReminders[position] = remove;
remove.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("The Array positioning of this remove view is: ", ""+v.getTag());
}
});
return view;
}
public void addReminder() {
Log.d("addReminder METHOD", "The Add Reminder method is running");
Spinner[] temp = new Spinner[shownReminders.length+1];
TextView[] temp2 = new TextView[removeReminders.length+1];
String [] temp3 = new String[reminders.length+1];
for(int i = 0; i < shownReminders.length; i++) {
temp[i] = shownReminders[i];
temp2[i] = removeReminders[i];
temp3[i] = reminders[i];
}
shownReminders = temp;
removeReminders = temp2;
reminders = temp3;
mAdapter.notifyDataSetChanged();//this just makes the adapter refresh itself
}
public void giveYourself(RemindersAdapter adapter) {
mAdapter = adapter;
}
public class MyOnReminderSelectedListener implements OnItemSelectedListener{
#Override
public void onItemSelected(AdapterView<?> parent, View view, int pos,
long id) {
int position = Integer.parseInt(parent.getTag().toString()); //gets the position of the Spinner and puts it in the same index in the reminders array
reminders[position] = parent.getItemAtPosition(pos).toString();
for(int i =0; i < reminders.length; i++) Toast.makeText(parent.getContext(), i+": "+reminders[i], Toast.LENGTH_SHORT).show();
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// Do nothing for now
}
}//end of MyOnReminderSelectedListener innerclass
}//end of Class
What runs in the Activity
reminderList = (ListView)findViewById(R.id.reminders_list);
reminderAdapter = new RemindersAdapter();
reminderAdapter.giveYourself(reminderAdapter);
reminderList.setAdapter(reminderAdapter);
TextView addReminder = (TextView)findViewById(R.id.add_reminder);
addReminder.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("TAG", "The onClick is running !");
reminderAdapter.addReminder();
}
});
I am at a loss because my code looks exactly like my test code, with some modifications in order for it to work with my app. But the information used by the Adapter is pretty much the same. I am going to post the test code as well so you guys can see the code that works.
Test Code
public class RemindersAdapter extends BaseAdapter{
Spinner[] shownReminders = new Spinner[1];
ArrayList<TextView> removeSpinner = new ArrayList<TextView>();
Context mContext;
public RemindersAdapter(Context context) {
mContext = context;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return shownReminders.length;
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return shownReminders[position];
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public View getView(int position, View view, ViewGroup parent) {
Log.d("TAG", "Number of times this is running"+position);
Log.d("TAG", "Address of the Spinner Object"+shownReminders[position]);
if(view == null) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
view = inflater.inflate(R.layout.reminder_spinner, parent, false);
}
Spinner reminderSpinner = (Spinner)view.findViewById(R.id.reminders_spinner);
reminderSpinner.setTag("1");
ArrayAdapter<CharSequence> reminderAdapter = ArrayAdapter.createFromResource(
parent.getContext(), R.array.reminders_array, android.R.layout.simple_spinner_item);
reminderAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
reminderSpinner.setAdapter(reminderAdapter);
reminderSpinner.setOnItemSelectedListener(new MyOnReminderSelectedListener());
shownReminders[position] = reminderSpinner;
TextView remove = (TextView)view.findViewById(R.id.remove_reminder);
remove.setTag(position);
removeSpinner.add(remove);
remove.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int pos = Integer.parseInt(v.getTag().toString());
removeSpinner.remove(pos);
Spinner[] temp = new Spinner[shownReminders.length-1];
for(int i =0; i < shownReminders.length; i++) {
if(i == pos || i > pos) {
temp[i-1] = shownReminders[i];
} else {
temp[i] = shownReminders[i];
}
}
//Here i should refresh somewhow
}
});
return view;
}
public void addReminder() {
Spinner[] temp = new Spinner[shownReminders.length+1];
for(int i = 0; i < shownReminders.length; i++) {
temp[i] = shownReminders[i];
}
shownReminders = temp;
}
/*
* Listener for when the reminder spinner gets a value the user entered
* */
public class MyOnReminderSelectedListener implements OnItemSelectedListener{
#Override
public void onItemSelected(AdapterView<?> parent, View view, int pos,
long id) {
//does nothing for now
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// Do nothing for now
}
}//end of MyOnReminderSelectedListener innerclass
I also have a question as to why the Adapter runs itself so much. For examples, using the Log, I noticed it calls getView() twice for no apparent reason. Its weird that it has this behavior. I guess I don't understand BaseAdapter so well.
This error will happen if you put a ListView inside a ScrollView. ListView itself does vertical scroll so it must not be put into a ScrollView.
An adapter will call getView when listView needs a new item to show. So, if your listView has no scroll, no new item will be created, and no call to getView will be made.
But you should not store all spinner objects, or create new objects in getView. That`s because it will be slow and maybe waste of memory.

Categories

Resources