I'm making NLevel expandable list using listview. I've added checkbox only last level data in list view. I have stuck in below scenario.
If I check checkbox then when I expand listview means checkbox gets automatically unchecked.I don't want it to be like that. If I checked checkbox it should stay checked until I uncheck manually.
Please anyone help me!! It's been two days I stuck here.
Here goes my code:
MainActivity.java
public class MainActivity extends Activity {
List<NLevelItem> list;
ListView listView;
Context context;
Button checkButton;
ArrayList<String>tempList;
CheckBox selected = null; //Make only one selection at a time
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listView1);
list = new ArrayList<NLevelItem>();
context = this;
checkButton = (Button)findViewById(R.id.buttons);
tempList = new ArrayList<String>();
//here we create 5 grandparent (top level) NLevelItems
//then foreach grandparent create a random number of parent (second level) NLevelItems
//then foreach parent create a random number of children (third level) NLevelItems
//we pass in an anonymous instance of NLevelView to the NLevelItem, this NLevelView is
//what supplies the NLevelAdapter with a View for this NLevelItem
Random rng = new Random();
final LayoutInflater inflater = LayoutInflater.from(this);
for (int i = 0; i < 5; i++) {
final NLevelItem grandParent = new NLevelItem(new SomeObject("GrandParent "+i),null, new NLevelView() {
#Override
public View getView(NLevelItem item) {
View view = inflater.inflate(R.layout.list_item, null);
TextView tv = (TextView) view.findViewById(R.id.textView);
//tv.setBackgroundColor(Color.GREEN);
String name = (String) ((SomeObject) item.getWrappedObject()).getName();
tv.setText(name);
return view;
}
});
list.add(grandParent);
int numChildren = rng.nextInt(4) + 1;
for (int j = 0; j < numChildren; j++) {
NLevelItem parent = new NLevelItem(new SomeObject("Parent "+j),grandParent, new NLevelView() {
#Override
public View getView(NLevelItem item) {
View view = inflater.inflate(R.layout.list_item, null);
TextView tv = (TextView) view.findViewById(R.id.textView);
//tv.setBackgroundColor(Color.YELLOW);
String name = (String) ((SomeObject) item.getWrappedObject()).getName();
tv.setText(name);
return view;
}
});
list.add(parent);
int children = rng.nextInt(3)+1;
for(int x=0; x<children;x++){
final NLevelItem childs = new NLevelItem(new SomeObject("Parent1 "+x),parent, new NLevelView() {
#Override
public View getView(NLevelItem item) {
View view = inflater.inflate(R.layout.list_item, null);
TextView tv = (TextView) view.findViewById(R.id.textView);
//tv.setBackgroundColor(Color.BLUE);
String name = (String) ((SomeObject) item.getWrappedObject()).getName();
tv.setText(name);
return view;
}
});
list.add(childs);
int grandChildren = rng.nextInt(5)+1;
for( int k = 0; k < grandChildren; k++) {
NLevelItem child = new NLevelItem(new SomeObject("child "+k),childs, new NLevelView() {
#Override
public View getView(NLevelItem item) {
View view = inflater.inflate(R.layout.check_list, null);
TextView tv = (TextView) view.findViewById(R.id.checktextView);
final String name = (String) ((SomeObject) item.getWrappedObject()).getName();
final CheckBox checkBox = (CheckBox)view.findViewById(R.id.check);
checkBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(selected != null){ //Edit
selected.setChecked(false);
}
selected = checkBox; //Edit
if(checkBox.isChecked()){
tempList.add((String) ((SomeObject)childs.getWrappedObject()).getName()+"+"+name);
}
else {
tempList.remove((String) ((SomeObject)childs.getWrappedObject()).getName()+"+"+name);
}
}
});
//tv.setBackgroundColor(Color.GRAY);
tv.setText(name);
return view;
}
});
list.add(child);
}
}
}
}
NLevelAdapter adapter = new NLevelAdapter(list);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
((NLevelAdapter)listView.getAdapter()).toggle(arg2);
((NLevelAdapter)listView.getAdapter()).getFilter().filter();
}
});
checkButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
for (int i=0;i<tempList.size();i++){
Toast.makeText(context,tempList.get(i),Toast.LENGTH_LONG).show();
}
}
});
}
class SomeObject {
public String name;
public SomeObject(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
}
NLevelAdapter.java
public class NLevelAdapter extends BaseAdapter {
List<NLevelItem> list;
List<NLevelListItem> filtered;
public void setFiltered(ArrayList<NLevelListItem> filtered) {
this.filtered = filtered;
}
public NLevelAdapter(List<NLevelItem> list) {
this.list = list;
this.filtered = filterItems();
}
#Override
public int getCount() {
return filtered.size();
}
#Override
public NLevelListItem getItem(int arg0) {
return filtered.get(arg0);
}
#Override
public long getItemId(int arg0) {
return 0;
}
#Override
public View getView(int arg0, View arg1, ViewGroup arg2) {
return getItem(arg0).getView();
}
public NLevelFilter getFilter() {
return new NLevelFilter();
}
class NLevelFilter {
public void filter() {
new AsyncFilter().execute();
}
class AsyncFilter extends AsyncTask<Void, Void, ArrayList<NLevelListItem> > {
#Override
protected ArrayList<NLevelListItem> doInBackground(Void...arg0) {
return (ArrayList<NLevelListItem>)filterItems();
}
#Override
protected void onPostExecute(ArrayList<NLevelListItem> result) {
setFiltered(result);
NLevelAdapter.this.notifyDataSetChanged();
}
}
}
public List<NLevelListItem> filterItems() {
List<NLevelListItem> tempfiltered = new ArrayList<NLevelListItem>();
OUTER: for (NLevelListItem item : list) {
//add expanded items and top level items
//if parent is null then its a top level item
if(item.getParent() == null) {
tempfiltered.add(item);
} else {
//go through each ancestor to make sure they are all expanded
NLevelListItem parent = item;
while ((parent = parent.getParent())!= null) {
if (!parent.isExpanded()) {
//one parent was not expanded
//skip the rest and continue the OUTER for loop
continue OUTER;
}
}
tempfiltered.add(item);
}
}
return tempfiltered;
}
public void toggle(int arg2) {
filtered.get(arg2).toggle();
}
}
Thanks in advance!!
i think you need to store the checkbox state in a boolean (is checked), and reflect that on the view, when getView() is called.
1- Add boolean checked to NLevelItem :
private boolean checked = false;
//add setter: setChecked(boolean)
//add getter isChecked()
2- Use that boolean in getView() (last one where checkbox is added)
#Override
public View getView(final NLevelItem item) {
// .......
final CheckBox checkBox = (CheckBox)view.findViewById(R.id.check);
checkBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//store checkbox state, note that NLevelItem item might need to be defined with 'final'
item.setChecked(checkBox.isChecked());
if(checkBox.isChecked()){
tempList.add((String) ((SomeObject)childs.getWrappedObject()).getName()+"+"+name);
}
else {
tempList.remove((String) ((SomeObject)childs.getWrappedObject()).getName()+"+"+name);
}
}//onClick()
}//setOnClickListener()
//update checkbox state from the corresponding NLevelItem
checkBox.setChecked(item.isChecked());
//.......
}//getView()
-EDIT:
to select 1 item, you need to iterate all items, set checked = false, but 1
i am not sure if you have to do it on:
List<NLevelItem> list;
or
List<NLevelListItem> filtered;
in the adapter class
private void selectOnly(int position){
for(int a=0;a<list.size();a++){
if(a == position){
list.get(a).setChecked(true);
continue;
}
list.get(a).setChecked(false);
}//for loop
notifyDataSetChanged(); // to update views (checkbox state)
}
Usage: selectOnly(15);
Use ViewHolder class to set and get Tag like this:
public class ListAdapter extends BaseAdapter {
private Context con;
private List<String> dataLt;
private static LayoutInflater inflater = null;
public ListAdapter(Context context, List<String> dataList){
con = context;
dataLt = dataList;
inflater = (LayoutInflater)con.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return dataLt.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
ViewHolder holder;
if(convertView==null){
/****** Inflate tabitem.xml file for each row ( Defined below ) *******/
vi = inflater.inflate(R.layout.list_item_search, null);
/****** View Holder Object to contain tabitem.xml file elements ******/
holder = new ViewHolder();
holder.textView = (TextView) vi.findViewById(R.id.textView);
/************ Set holder with LayoutInflater ************/
vi.setTag( holder );
}
else
holder=(ViewHolder)vi.getTag();
return vi;
}
public static class ViewHolder{
TextView textView;
}
}
Hope this may help.
Related
a weird problem happened with me, when i apply something (like drop down, visibility, background) on a linear at position, it will also apply it on other position.
for understand me this a picture of my problem :
and this is my Adapter, whats wrong ?
public class Listview1Adapter extends BaseAdapter {
ArrayList<HashMap<String, Object>> data;
public Listview1Adapter(ArrayList<HashMap<String, Object>> arr) {
data = arr;
}
#Override
public int getCount() {
return data.size();
}
#Override
public HashMap<String, Object> getItem(int index) {
return data.get(index);
}
#Override
public long getItemId(int index) {
return index;
}
#Override
public View getView(final int _position, View _v, ViewGroup _container) {
LayoutInflater _inflater = (LayoutInflater) getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = _v;
if (v == null) {
v = _inflater.inflate(R.layout.online_block_list, null);
}
final ImageView drop_more = v.findViewById(R.id.drop_more);
final LinearLayout linearMore = v.findViewById(R.id.linearMore);
final LinearLayout linearDro = v.findViewById(R.id.linearDro);
linearDro.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (linearMore.getVisibility() == View.GONE) {
final android.transition.ChangeBounds transition = new android.transition.ChangeBounds(); transition.setDuration(200L);
android.transition.TransitionManager.beginDelayedTransition(listview1, transition);
linearMore.setVisibility(View.VISIBLE);
ObjectAnimator.ofFloat(drop_more, View.ROTATION, 0f, 180f).setDuration(300).start();
} else {
final android.transition.ChangeBounds transition = new android.transition.ChangeBounds(); transition.setDuration(200L);
android.transition.TransitionManager.beginDelayedTransition(listview1, transition);
linearMore.setVisibility(View.GONE);
ObjectAnimator.ofFloat(drop_more, View.ROTATION, 180f, 0f).setDuration(300).start();
}
}
});
ListView reuse views returned by Listview1Adapter.getView() method. You get a situation when view for some item change itself - the state of View instance(object) was changed (expanded). Then ListView pass as an argument of Listview1Adapter.getView() method a same View's instance for other item - this view already expanded.
You should save state of view for each item of ListView (in your case for data ArrayList) and restore it for each item in getView() method. It might look like:
public class Listview1Adapter extends BaseAdapter {
final ArrayList<ItemState> data;
public Listview1Adapter(ArrayList<ItemState> arr) {
data = arr;
}
private static class ItemState {
final HashMap<String, Object> data;
boolean isExpanded;
public ItemState(final HashMap<String, Object> data, final boolean isExpanded) {
this.data = data;
this.isExpanded = isExpanded;
}
}
#Override
public int getCount() {
return data.size();
}
#Override
public HashMap<String, Object> getItem(int index) {
return data.get(index).data;
}
#Override
public long getItemId(int index) {
return index;
}
#Override
public View getView(final int _position, View _v, ViewGroup _container) {
LayoutInflater _inflater = (LayoutInflater) getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = _v;
if (v == null) {
v = _inflater.inflate(R.layout.online_block_list, null);
}
final ImageView drop_more = v.findViewById(R.id.drop_more);
final LinearLayout linearMore = v.findViewById(R.id.linearMore);
final LinearLayout linearDro = v.findViewById(R.id.linearDro);
if (data.get(_position).isExpanded) { // check current view state for item
linearMore.setVisibility(View.VISIBLE); // restore view state for current item
} else {
linearMore.setVisibility(View.GONE); // restore view state for current item
}
linearDro.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (linearMore.getVisibility() == View.GONE) {
final android.transition.ChangeBounds transition = new android.transition.ChangeBounds();
transition.setDuration(200L);
android.transition.TransitionManager.beginDelayedTransition(listview1, transition);
linearMore.setVisibility(View.VISIBLE);
data.get(_position).isExpanded = true; // save view state for item
ObjectAnimator.ofFloat(drop_more, View.ROTATION, 0f, 180f).setDuration(300).start();
} else {
final android.transition.ChangeBounds transition = new android.transition.ChangeBounds();
transition.setDuration(200L);
android.transition.TransitionManager.beginDelayedTransition(listview1, transition);
linearMore.setVisibility(View.GONE);
data.get(_position).isExpanded = false; // save view state for item
ObjectAnimator.ofFloat(drop_more, View.ROTATION, 180f, 0f).setDuration(300).start();
}
}
});
return v;
}
}
You have many options to convert your items to ItemState objects, I show a few bellow:
final ArrayList<HashMap<String, Object>> listMapTest = new ArrayList<>(); // input data
// 1th
final ArrayList<ItemState> viewListMapTest_1 = listMapTest.stream().map(item -> new ItemState(item, false)).collect(Collectors.toCollection(ArrayList::new));
// 2th:
final ArrayList<ItemState> viewListMapTest_2 = new ArrayList<ItemState>() {{
for (HashMap<String, Object> item : listMapTest) add(new ItemState(item, false));
}};
// 3th:
final ArrayList<ItemState> viewListMapTest_3 = new ArrayList<>(listMapTest.size());
for (int i = 0; i < viewListMapTest_3.size(); i++) {
viewListMapTest_3.set(i, new ItemState(listMapTest.get(i), false));
}
I have a little bit problem.In my activity there is two Adapter one is for color selection and another is for size selection. While i clicked one of the item of color then recently the available size adapter should be change but i got problem in size adapter. it changes only when i click the size item. I research and try to solve problem but it doesnt works for me.
Here is my code.
AddToCartActivity.java
public class AddToCartActivity extends BaseActivity{
#Override
protected int getLayout() {
return R.layout.activity_add_to_cart;
}
#Override
protected void init() {
//api called here
}
// response of api
#Override
public void productDetail(ProductCommonModel productCommonModel,
ArrayList<ProductChildModel> productChildModels, HashMap<Integer,
ArrayList<ChildAttributeModel>> childWithAttribute, HashMap<Integer,
ArrayList<ChildImageModel>> childWithImages,
ArrayList<com.hazesoft.dokan.singleproductdetail.model.ColorModel>
colorModels, ArrayList<SizeModel> sizeModels,
ArrayList<RelatedProductModel> relatedProductModels) {
this.productCommonModel = productCommonModel;
this.productChildModels = productChildModels;
this.childWithAttribute = childWithAttribute;
this.childWithImages = childWithImages;
this.colorModels = colorModels;
this.sizeModels = sizeModels;
this.relatedProductModels = relatedProductModels;
tvProductName.setText(productCommonModel.getName());
if (productCommonModel.getSpecialPrice() == 0) {
tvSellingPrice.setText(getString(R.string.rs) + productCommonModel.getSellingPrice());
tvDiscount.setVisibility(View.GONE);
tvSpecialPrice.setVisibility(View.GONE);
} else {
tvSpecialPrice.setText(getString(R.string.rs) + productCommonModel.getSpecialPrice());
tvSellingPrice.setText(getString(R.string.rs) + productCommonModel.getSellingPrice());
tvSellingPrice.setPaintFlags(tvSellingPrice.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
tvDiscount.setText(productCommonModel.getDiscount() + getString(R.string.percentage));
}
setChildDetail(childWithAttribute, productChildModels);
setColorModel(colorModels);
setSizeModel(sizeModels);
quantity = Integer.parseInt(tvQuantityCart.getText().toString());
}
// setcolor adapter
private void setColorModel(ArrayList<ColorModel> colorModels) {
MyColorGridViewAdapter adapter = new MyColorGridViewAdapter(this, colorModels);
gvColor.setAdapter(adapter);
gvColor.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
adapter.setSelectedPostion(position);
adapter.notifyDataSetChanged();
}
});
}
// set size adapter
private void setSizeModel(ArrayList<SizeModel> sizeModels) {
sizeCustomModels = new ArrayList<>();
for(int i=0;i<sizeModels.size();i++){
sizeCustomModels.add(new SizeCustomModel(sizeModels.get(i).getAttName(),0));
}
setCustomSizeModelToAdapter(sizeCustomModels);
}
// this is code when i click color and change the size adapter but size doesnt change recently only changes when i click any item of the size
public void getSelectedC0lor(String color) {
selectedColor = color;
selectedSize=null;
sizeCustomModels = new ArrayList<>();
availableSize = new ArrayList<>();
for (int i = 0; i < skuColorSIzeList.size(); i++) {
if (skuColorSIzeList.get(i).getColor().equals(selectedColor)) {
availableSize.add(skuColorSIzeList.get(i).getSize());
}
}
for(int i=0;i<sizeModels.size();i++){
String size = null;
int status=0;
for(int j=0;j<availableSize.size();j++){
if(sizeModels.get(i).getAttName().equals(availableSize.get(j))){
size = sizeModels.get(i).getAttName();
status = 1;
break;
}else {
size = sizeModels.get(i).getAttName();
status = 0;
}
}
sizeCustomModels.add(new SizeCustomModel(size,status));
}
sizeRecylerAdapter.getNewModel(sizeCustomModels);
/*sizeRecylerAdapter = new MyCustomSizeRecylerAdapter(sizeCustomModels,this);
rvSize.setAdapter(sizeRecylerAdapter);
sizeRecylerAdapter.notifyDataSetChanged();*/
/*setCustomSizeModelToAdapter(sizeCustomModels);*/
}
}
MyColorGridViewAdapter.java
public class MyColorGridViewAdapter extends BaseAdapter {
Context context;
List<ColorModel> colorModelList;
String select_color;
boolean ch =false;
int checkPosition = -1;
public MyColorGridViewAdapter(Context context, List<ColorModel> colorModelList) {
this.context = context;
this.colorModelList = colorModelList;
}
public void setSelectedPostion(int postion){
this.checkPosition = postion;
}
#Override
public int getCount() {
return colorModelList.size();
}
#Override
public Object getItem(int position) {
return colorModelList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if(convertView==null){
convertView = LayoutInflater.from(context).inflate(R.layout.custom_color_list_item,null);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
}else {
holder = (ViewHolder) convertView.getTag();
}
Picasso.with(context).load(colorModelList.get(position).getImage()).into(holder.ivImage);
holder.tvColorName.setText(colorModelList.get(position).getAttName());
if(checkPosition==position){
holder.ivChecked.setVisibility(View.VISIBLE);
select_color = colorModelList.get(position).getAttName();
if( context instanceof AddToCartActivity){
((AddToCartActivity) context).getSelectedC0lor(select_color);
}
}else {
holder.ivChecked.setVisibility(View.GONE);
}
if(colorModelList.size()==1){
holder.ivChecked.setVisibility(View.VISIBLE);
select_color = colorModelList.get(position).getAttName();
if( context instanceof AddToCartActivity){
((AddToCartActivity) context).getSelectedC0lor(select_color);
}
}
return convertView;
}
class ViewHolder{
#BindView(R.id.view)
LinearLayout view;
#BindView(R.id.tv_color_name)
TextViewHelper tvColorName;
#BindView(R.id.iv_image)
ImageView ivImage;
#BindView(R.id.iv_checked)
ImageView ivChecked;
public ViewHolder(View view) {
ButterKnife.bind(this,view);
}
}
}
MyCustomSizeRecylerAdapter.java
public class MyCustomSizeRecylerAdapter extends RecyclerView.Adapter<MyCustomSizeRecylerAdapter.MyViewHolder> {
ArrayList<SizeCustomModel> sizeModels;
Context context;
int checkPosition = -1;
String selectedSize;
public MyCustomSizeRecylerAdapter(ArrayList<SizeCustomModel> sizeModels, Context context) {
this.sizeModels = sizeModels;
this.context = context;
}
public void getNewModel(ArrayList<SizeCustomModel> customModels) {
sizeModels.clear();
this.sizeModels = customModels;
selectedSize = null;
Log.d("sizemodel", "getNewModel: " + new Gson().toJson(sizeModels));
notifyDataSetChanged();
}
public void getSelectedPosition(int position) {
checkPosition = position;
notifyDataSetChanged();
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.size_adapter, parent, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.tv_sizeName.setText(sizeModels.get(position).getSize());
holder.ll_sizeAdapter.setBackgroundResource(R.drawable.ellipse_register);
if (sizeModels.get(position).getStock_Status() == 0) {
holder.ll_mainview.setClickable(false);
holder.ll_sizeAdapter.setBackgroundResource(R.color.blue_700);
} else if (sizeModels.get(position).getStock_Status() == 1) {
holder.ll_sizeAdapter.setBackgroundResource(R.drawable.ellipse_register);
if (checkPosition == position) {
holder.ll_sizeAdapter.setBackgroundResource(R.drawable.ellipse_green);
holder.tv_sizeName.setTextColor(context.getResources().getColor(R.color.white));
selectedSize = sizeModels.get(position).getSize();
if (context instanceof AddToCartActivity) {
((AddToCartActivity) context).getSelectSize(selectedSize);
}
} else {
holder.ll_sizeAdapter.setBackgroundResource(R.drawable.ellipse_register);
holder.tv_sizeName.setTextColor(context.getResources().getColor(R.color.tv_black));
}
if (sizeModels.size() == 1) {
holder.ll_sizeAdapter.setBackgroundResource(R.drawable.ellipse_green);
holder.tv_sizeName.setTextColor(context.getResources().getColor(R.color.white));
selectedSize = sizeModels.get(position).getSize();
if (context instanceof AddToCartActivity) {
((AddToCartActivity) context).getSelectSize(selectedSize);
}
}
}
}
#Override
public int getItemCount() {
return sizeModels.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
#BindView(R.id.tv_sizeName)
TextView tv_sizeName;
#BindView(R.id.ll_sizeAdapter)
LinearLayout ll_sizeAdapter;
#BindView(R.id.main_view)
LinearLayout ll_mainview;
public MyViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
}
At first both adapter will set data and after click color item the size adapter must be change but it only changes when i click any of the item. adapter.notifyDataSetChanged() doesnt work here for me.
Both Adapter set
When i click color item but doesnt change size adapter
when i click size item only change size adapter
Use Interface to bridge with two adapter and communicate with each other.
i am trying to get data from Textviews in a listview after has been modified by the user.
So then the user click on the row the "descrec" Textview will changed to "completed"
listView.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
TextView text2 = (TextView) view.findViewById(R.id.descrec);
if(text2.getText().toString().equals("Selected"))
{
text2.setText(Outstanding.outDesc[(int)id]);
}
else
{
text2.setText("Selected");
}
Log.i("you selected row number",String.valueOf(id));
}
});
once user finish selecting rows and hit the "submit" button i should print all the rows with "selected" String in "descrec" Textview but it's printing nothing.
public void submit (View view)
{
for (int i = 0; i < listView.getCount(); i++)
{
v = listView.getAdapter().getView(i, null, null);
TV = (TextView) v.findViewById(R.id.descrec);
if (TV.getText().toString().equals("Selected"))
{
//just to make sure descrec text has beeen changed somewhere
Log.i("descrec", (String) TV.getText());
}
//to check the Textview anyway
Log.i("descrec value", (String) TV.getText());
}
}
and the result of printing the whole rows' "descrec" giving the original values of the Textview before the user changed it to "Selected".
Here is the results after selecting rows and hitting submit button.
here is the full code
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_outstanding);
new MyAsync().execute();
}
class MyAsync extends AsyncTask<Void, Void, Void> {
protected void onPreExecute() {
Log.i("preexcute","first");
listView = (ListView)findViewById(R.id.listviewout);
Contactadapter2 = new contactadapter2(Outstanding.this , R.layout.rowrecord_layout);
listView.setAdapter(Contactadapter2);
BackgroundWorker Backgroundworker = new BackgroundWorker(Outstanding.this);
Backgroundworker.execute(type,Homescreen.userID);
}
#Override
protected Void doInBackground(Void... arg0) {
return null;
}
#Override
protected void onPostExecute(final Void unused) {
Log.i("postexcute","second");
for (int i = 0; i < outrecieptID.length; i++) {
Log.i("test", valueOf(i) + "out of" + valueOf(outrecieptID.length));
Contacts2 contacts2 = new Contacts2(Outstanding.outrecieptID[i], Outstanding.outAmount[i], Outstanding.outDesc[i]);
Contactadapter2.add(contacts2);
}
for(int i=0 ; i < listView.getCount() ; i++) {
v[i] = listView.getAdapter().getView(i, null, null);
}
listView.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
TextView text2 = (TextView) view.findViewById(R.id.descrec);
TV = (TextView) v[(int)id].findViewById(R.id.descrec);
if(text2.getText().toString().equals("Selected"))
{
text2.setText(Outstanding.outDesc[(int)id]);
}else
{
text2.setText("Selected");
TV.setText("Selected");
}
Log.i("you selected row number",String.valueOf(id));
}
});
}
}
public void submit (View view)
{
for (int i = 0; i < listView.getCount(); i++) {
// v = listView.getAdapter().getView(i, null, null);
TV = (TextView) v[i].findViewById(R.id.descrec);
if (TV.getText().toString().equals("Selected"))
{
//just to make sure descrec text has beeen changed somewhere
Log.i("descrec", (String) TV.getText());
}
//to see the Textview anyway
Log.i("descrec value", (String) TV.getText());
}
}
Here is the contactadapter code :
public class contactadapter2 extends ArrayAdapter {
List list= new ArrayList();
public contactadapter2(Context context, int resource) {
super(context, resource);
}
public void add(Contacts2 object) {
super.add(object);
list.add(object);
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int position) {
return list.get(position);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row;
row=convertView;
ContentHolder contentHolder;
if(row==null)
{
LayoutInflater layoutInflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = layoutInflater.inflate(R.layout.rowrecord_layout,parent,false);
contentHolder = new ContentHolder();
contentHolder.recieptidout=(TextView) row.findViewById(R.id.recieptidrec);
contentHolder.amountout= (TextView) row.findViewById(R.id.amountrec);
contentHolder.descout= (TextView) row.findViewById(R.id.descrec);
row.setTag(contentHolder);
}
else
{
contentHolder = (ContentHolder)row.getTag();
}
Contacts2 contacts2 = (Contacts2) this.getItem(position);
contentHolder.recieptidout.setText(contacts2.getrecieptidrec());
contentHolder.amountout.setText(contacts2.getamountrec());
contentHolder.descout.setText(contacts2.getdescrec());
return row;
}
static class ContentHolder
{
TextView recieptidout,amountout,descout;
}
You should update the model with the "Selected" Text . Otherwise it wont work . Because when you call v = listView.getAdapter().getView(i, null, null) It will bind the data from your arraylist . So it will change your text that you set in the itemclick listener.
try to change some thing like this,
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView text2 = (TextView) view.findViewById(R.id.descrec);
if(text2.getText().toString().equals("Selected"))
{
text2.setText(Outstanding.outDesc[(int)id]);
}
else
{
text2.setText("Selected");
}
Contacts2 contacts2 = parent.getAdapter().getItem(position);
contacts2.setdescrec(text2.getText().toString());
Log.i("you selected row number",String.valueOf(id));
}
});
In each row, I have a button and a textView. When the Button is clicked, It successfully sets the textView to a new value in that row. However, When I call ParseQuery() in GetView(); and try to do object.put("objectName", num) The only value that is populated to my Parse-Server is the last row. My SetTag(); and GetTag(); and ViewHolder class is correct When I click the button, I believe android studio is unsure of which row's TextView to populate so it just automatically populates the last row's TextView.
Custom ListView Adapter Class
public class CustomFeedListViewAdapter extends BaseAdapter {
String likesString;
int position;
private Context mContext;
private ArrayList<HashMap<String, String>> feed;
private static LayoutInflater inflater = null;
ParseObject parseObFeed;
public CustomFeedListViewAdapter(Context context, ArrayList<HashMap<String, String>> data) {
super();
this.mContext = context;
this.feed = data;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return feed.size();
}
#Override
public Object getItem(int i) {
return feed.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(final int i, View view, ViewGroup viewGroup) {
position = i;
final ViewHolder holder;
if (view == null) {
view = inflater.inflate(R.layout.feed_list_row, viewGroup, false);
holder = new ViewHolder();
holder.feedProfilePic = (ImageView) view.findViewById(R.id.feedProfilePic);
holder.feedUsername = (TextView) view.findViewById(R.id.feedUsernameId);
holder.feedNumOfLikes = (TextView) view.findViewById(R.id.feedNumofLikes);
holder.feedUpVoteButton = (Button) view.findViewById(R.id.feedUpVoteButton);
view.setTag(holder);
HashMap<String, String> mFeed = new HashMap<>();
mFeed = feed.get(i);
holder.feedNumOfLikes.setText(mFeed.get("likes"));
likesString = mFeed.get("likes");
holder.mLikes = Integer.valueOf(likesString);
position = i;
}
else{
position = i;
holder = (ViewHolder) view.getTag();
}
holder.feedUpVoteButton.setTag(position);
ParseQuery<ParseObject> query = new ParseQuery<ParseObject>("FeedItem");
query.addDescendingOrder("createdAt");
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> objects, ParseException e) {
if(e == null){
for (final ParseObject object : objects) {
holder.feedUpVoteButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ParseObject[] mParseObject = new ParseObject[feed.size()];
int pos = (Integer) v.getTag();
mParseObject[pos] = object;
holder.likes[pos] = holder.mLikes;
mParseObject[pos].put("likes", holder.likes[pos]);
mParseObject[pos].saveInBackground();
holder.feedNumOfLikes.setText(String.valueOf(holder.likes[pos]
));
}
});
}
}
}
});
return view;
}
class ViewHolder {
ImageView feedProfilePic;
TextView feedUsername;
TextView feedNumOfLikes;
TextView feedFeedItem;
TextView feedDate;
TextView feedNumofReplies;
Button feedUpVoteButton;
Button feedDownVoteButton;
Button feedCommentButton;
ListView feedListView;
int likes[] = new int[feed.size()];
int mLikes;
}
}
I am making a custom list and I want to save the text of some TextFile which is in R.id.quantity.
I also want to save the state of a checkbox. I tried to manage checked state of a checkbox in a list.
The List contains other view controls. I have put them in a Viewholder class. I am initializing qtyTxtV with some initial array value, once an event occurs in this code the value of the array changes but the list contents gets erased. Please help out.
Now this code is giving me a null pointer exception:
class MyAdapter1 extends BaseAdapter {
Context context;
ArrayList<Integer> price = new ArrayList<Integer>();
ArrayList<String> names = new ArrayList<String>();
public static HashMap<Integer, String> myList = new HashMap<Integer, String>();
static class ViewHolder {
public TextView tvQuantityName, tvPrice, tvDishName;
public ImageView imv1, imv2, imv3, imv4, imv5;
public EditText edtQty;
public CheckBox chkAdd;
}
public MyAdapter1(VegDetail vegDetail, ArrayList<String> names2,
ArrayList<Integer> price2) {
this.context = vegDetail;
this.names = names2;
this.price = price2;
}
#Override
public int getCount() {
return names.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#SuppressWarnings("null")
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View row = convertView;
ViewHolder holder = null;
// View row = inflater.inflate(R.layout.rowlayout, parent, false);
if (row == null) {
LayoutInflater inflater = LayoutInflater.from(context);
row = inflater.inflate(R.layout.rowlayout, parent, false);
holder.edtQty = (EditText) row.findViewById(R.id.quantity);
holder.imv1 = (ImageView) row.findViewById(R.id.star1);
holder.imv2 = (ImageView) row.findViewById(R.id.star2);
holder.imv3 = (ImageView) row.findViewById(R.id.star3);
holder.imv4 = (ImageView) row.findViewById(R.id.star4);
holder.imv5 = (ImageView) row.findViewById(R.id.star5);
holder.tvDishName = (TextView) row.findViewById(R.id.item_name);
holder.tvPrice = (TextView) row.findViewById(R.id.price1);
holder.tvQuantityName = (TextView) row.findViewById(R.id.qtyTxtV);
holder.chkAdd = (CheckBox) row.findViewById(R.id.chkAdd);
EditText edtQty = (EditText) row.findViewById(R.id.quantity);
edtQty.setText(VegDetail.qtyArray[position].toString());
CheckBox chkAdd = (CheckBox) row.findViewById(R.id.chkAdd);
chkAdd.setSelected(VegDetail.chkArray[position]);
holder.edtQty.addTextChangedListener(new TextWatcher() {
public void onTextChanged(final CharSequence s,
final int start, final int before, final int count) {
}
public void afterTextChanged(final Editable s) {
int newValue;
final String boxContents = s.toString();
if (!boxContents.isEmpty()) {
try {
newValue = Integer.parseInt(boxContents);
VegDetail.qtyArray[position] = newValue;
} catch (final Exception exc) {
VegDetail.qtyArray[position] = 0;
} finally {
}
} else {
VegDetail.qtyArray[position] = 0;
}
}
public void beforeTextChanged(final CharSequence s,
final int start, final int count, final int after) {
}
});
row.setTag(holder);
} else {
holder = (ViewHolder) row.getTag();
}
CheckBox chkAdd=(CheckBox)row.findViewById(R.id.chkAdd);
chkAdd.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
//VegDetail is another class where I gonna use checked list's states
VegDetail.chkArray[position] = isChecked;
}
});
final TextView tv1 = (TextView) row.findViewById(R.id.item_name);
TextView tv2 = (TextView) row.findViewById(R.id.price1);
final TextView tvQty = (TextView) row.findViewById(R.id.quantity);
tv1.setText(names.get(position));
tv1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context,
"itme name is=>" + tv1.getText().toString(),
Toast.LENGTH_LONG).show();
}
});
tv2.setText("Rs:" + price.get(position));
return row;
}
}
The NPE must be at line :
holder.edtQty = (EditText) row.findViewById(R.id.quantity);
since holder is NULL as you have just defined above...ViewHolder holder = null