selected item of listview remain at same position after notifyDataSetChanged - android

I implemented a simple listview with an option to select each time only one item from it, this functionality is working properly.
Also I have a button for sorting the records in Asc or Desc order, when I am selecting a record and after that I am sorting the records the selector of the old record remains in the same old position, even when the selected position is updated different position.
MainActivity:
public class MainActivity extends Activity
{
private ListView _listView;
private PersonAdapter _adapter;
private Button _sortBtn;
private List<Person> _data;
private int _sort;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
_listView = (ListView) findViewById(R.id.list);
_sortBtn = (Button) findViewById(R.id.sort_list_btn);
_sort = 1;
_data = new ArrayList<Person>();
_data.add(new Person("abc", "defg", 1));
_data.add(new Person("aaa", "defg", 12));
_data.add(new Person("ccc", "defg", 13));
_data.add(new Person("bb", "defg", 14));
_data.add(new Person("aa", "defg", 144));
_data.add(new Person("fff", "defg", 199));
_adapter = new PersonAdapter(this, _data);
_listView.setAdapter(_adapter);
_sortBtn.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
Comparator<Person> sortById = Person.getComperatorByFirstName(_sort);
Collections.sort(_data, sortById);
_adapter.setData(_data);
_sort = -_sort;
}
});
}
public static class Person
{
public String _fName;
public String _lName;
public int _age;
public boolean _selected;
public Person(String fName, String lName, int age)
{
_fName = fName;
_lName = lName;
_age = age;
}
public static Comparator<Person> getComperatorByFirstName(final int ascendingFlag)
{
return new Comparator<Person>()
{
#Override
public int compare(Person patient1, Person patient2)
{
return patient1._fName.compareTo(patient2._fName) * ascendingFlag;
}
};
}
}
}
listView adapter
public class PersonAdapter extends BaseAdapter
{
private Context _con;
private List<Person> _data;
public PersonAdapter(Context context, List<Person> data)
{
_con = context;
_data = data;
}
#Override
public int getCount()
{
// TODO Auto-generated method stub
return _data.size();
}
#Override
public Person getItem(int position)
{
return _data.get(position);
}
#Override
public long getItemId(int position)
{
// TODO Auto-generated method stub
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
Holder h = null;
if (convertView == null)
{
h = new Holder();
convertView = LayoutInflater.from(_con).inflate(R.layout.item_layout, parent, false);
h._backgroundItem = (LinearLayout) convertView.findViewById(R.id.item_layout);
h._fName = (TextView) convertView.findViewById(R.id.f_name);
h._lName = (TextView) convertView.findViewById(R.id.l_name);
h._age = (TextView) convertView.findViewById(R.id.age);
convertView.setTag(h);
}
else
{
h = (Holder) convertView.getTag();
}
Person p = getItem(position);
h._fName.setText(p._fName);
h._lName.setText(p._lName);
h._age.setText(String.valueOf(p._age));
h._backgroundItem.setActivated(p._selected);
return convertView;
}
public void setData(List<Person> data)
{
_data = data;
notifyDataSetChanged();
}
private static class Holder
{
public LinearLayout _backgroundItem;
public TextView _fName;
public TextView _lName;
public TextView _age;
}
}
item layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/item_layout"
android:layout_width="match_parent"
android:layout_height="48dp"
android:orientation="horizontal"
android:background="#drawable/list_selector"
android:weightSum="3" >
<TextView
android:id="#+id/f_name"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<TextView
android:id="#+id/l_name"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<TextView
android:id="#+id/age"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
I tried already to use clearChoices but after sorting I do not see the selector at all, also I tried to change the choise mode from single mode to none and then again single but without any success.

It is because you are switching the contents of the items inside the list item, but the click is bound to the position withing the ListView, therefore it doesn't "update" to the new position of the item.
I suggest you to programatically click on the new item when you finish the sorting.
Get the ID of the clicked item
public int getItemPosition(long id)
{
for (int position=0; position<mList.size(); position++)
if (mList.get(position).getId() == id)
return position;
return 0;
}
then after the sorting do the click
mList.performItemClick(
mList.getAdapter().getView(mActivePosition, null, null),
mActivePosition,
mList.getAdapter().getItemId(mActivePosition));
hope it helps!

I suggest to store the id of the selected item when it is selected, and after order the dataset, search for that id and re-select it.

Related

Added items to cart list

I have created an android application. in that application when I click on add, item added to the array list and this array list I want to show in Cart Activity. how to do that.
here is my activity1
public void addShirt(View view) {
MainActivity.cartItems.add(getString(R.string.shirt));
}
public void addPant(View view) {
MainActivity.cartItems.add(getString(R.string.pant));
}
public void view(View view) {
Intent i =new Intent(OnlyIron.this,CartActivity.class);
startActivity(i);
}
and cart activity is
for(int i=0; i<MainActivity.cartItems.size();i++) {
Toast.makeText(this, "item : " + MainActivity.cartItems.get(i), Toast.LENGTH_SHORT).show();
}
it showing toast but I enter code here want this show in listview
First lets Create model class and store data in it.
public class Cart {
private String id;
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Now to add items in that list i would call it this way :
private ArrayList<Cart > cart_array;
cart_array= new ArrayList<>();
Cart cart1 = new Cart ();
cart.setId("1");
cart.setName("first product");
Cart cart2 = new Cart ();
cart.setId("2");
cart.setName("first product");
Cart cart3 = new Cart ();
cart.setId("3");
cart.setName("first product");
//and than add your model into array
cart_array.add(cart1);
cart_array.add(cart2);
cart_array.add(cart3);
//and finaly set your adapter
Cart_Adapter adapter = new Cart_Adapter(cart_array, getActivity());
Recycler.setAdapter(adapter );
Please take a list view in CartActivity & create an Custom Adapter as according to your need(UI). Pass the MainActivity.cartItems this list to Adapter. It will start to show in your CartActivity.
You can see below example:
public class CustomAdapter extends BaseAdapter{
Activity mContext;
public ArrayList<String> mCartList = new ArrayList<String>();
private LayoutInflater mInflater=null;
public CustomAdapter(Activity activty, ArrayList<String> list)
{
this.mContext = activty;
mInflater = activty.getLayoutInflater();
this.mCartList=list;
}
#Override
public int getCount() {
if (mCartList != null){
return mCartList.size();
} else{
return 0;
}
}
#Override
public String getItem(int arg0) {
return mCartList.get(arg0);
}
#Override
public long getItemId(int index) {
return index;
}
#Override
public View getView(final int position, View convertView, ViewGroup arg2) {
final ViewHolder holder;
if (convertView == null ) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.item_layout, null);
holder.mItemNameTV= (TextView) convertView.findViewById(R.id.itemtv);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
holder.mNameTV.setText(mCartList.get(position));
return convertView;
}
private static class ViewHolder {
TextView mNameTV;
}
}
// Item Layout
<LinearLayout
android:layout_width="match_parent"
android:layout_height="#dimen/forty_dp"
android:gravity="center_horizontal"
android:orientation="vertical">
<TextView
android:id="#+id/fieldTV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/five_dp"
android:layout_weight="0.4"
android:padding="#dimen/ten_dp"
android:text="Custom Field"
android:textColor="#color/dark_gray_color"
android:textSize="#dimen/normal_font_size"
android:visibility="visible" />
</LinearLayout>
// Let Suppose your CartActivity is following:
ListView mListView = (ListView)findViewById(R.id.listview);
CustomAdapter adapter = new CustomAdapter(this, MainActivity.cartItems);
mListView.setAdapter(adapter);

Click button inside listview then trigger gridview to load its button list on android studio

I have a listview, from database (category list) and i want to load gridview (product gridview) when i click any button in the category listview, i'm able to make the listview and gridview, but cannot connect them, since im still new at android programming and have no clue to do it.
my main purpose is:
List category
on click on the category button will load gridview of product button
on click product button will add the product id to table cart
ps: if you notice i do SQL query in the mainActivity class, i still new at the code so i tried my best first before convert into better practice.
Any suggestion to do it?
Here i include my snippet:
Category.java (setter and getter)
public class Category {
private int _id;
private String _name;
public Category() {
}
public Category(int id, String name) {
this._id = id;
this._name = name;
}
public Category(String name) {
this._name = name;
}
public int getID() {
return this._id;
}
public void setID(int id) {
this._id = id;
}
public String get_name()
{
return this._name;
}
public void set_name(String name)
{
this._name = name;
}
}
CategoryListAdapter.java
public class CategoryListAdapter extends BaseAdapter {
private ArrayList<Category> listData;
private LayoutInflater layoutInflater;
public CategoryListAdapter(Context aContext, ArrayList<Category> listData) {
this.listData = listData;
layoutInflater = LayoutInflater.from(aContext);
}
#Override
public int getCount() {
return listData.size();
}
#Override
public Object getItem(int position) {
return listData.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
CategoryListAdapter.ViewHolder holder;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.listview_category, null);
holder = new CategoryListAdapter.ViewHolder();
holder.btnCategory = (Button) convertView.findViewById(R.id.btnCategory);
convertView.setTag(holder);
} else {
holder = (CategoryListAdapter.ViewHolder) convertView.getTag();
}
holder.btnCategory.setText(listData.get(position).get_name());
return convertView;
}
static class ViewHolder {
Button btnCategory;
}
}
listview_category.xml (layout that will be repeated)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:textStyle="bold"
android:textSize="16dp"
android:id="#+id/btnCategory"
android:focusable="false"
android:focusableInTouchMode="false"
android:background="#drawable/button_category"/>
</LinearLayout>
listview inside MainActivity
<ListView
android:id="#+id/listviewCategory"
android:layout_margin="10dp"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
java inside MainActivity
protected void onCreate(Bundle savedInstanceState) {
...
/* LIST CATEGORY TO LOAD PRODUCT */
ArrayList list_category = getListCategory();
final ListView listview_category = (ListView) findViewById(R.id.listviewCategory);
listview_category.setAdapter(new CategoryListAdapter(this, list_category));
listview_category.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> a, View v, int position,
long id) {
Log.d(TAG, "click cat");
//Give product list an id from category_id get from here
}
});
...
}
/* List Category for selecting category product */
private ArrayList getListCategory() {
SQLiteDatabase mydatabase = openOrCreateDatabase("posDb",MODE_PRIVATE,null);
Cursor resultSet = mydatabase.rawQuery("Select * from categories",null);
ArrayList<Category> results = new ArrayList<Category>();
if (resultSet.moveToFirst()) {
do {
Category categoriesData = new Category();
categoriesData.set_name(resultSet.getString(1));
results.add(categoriesData);
} while (resultSet.moveToNext());
}
return results;
}
The grid of product mostly the same as category, but load product from database which later i want to onclick the product button to save record to cart table
on Click on button will add the product id in to table_cart
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// ArrayList list_category = getListCategory();
int id[]={1, 2, 3, 4, 5};
String categoryName[]={"category1","category2","category3","category4","category5"};
ArrayList<Category> listData=new ArrayList<>();
Category category;
for (int i=0; i<id.length; i++)
{
category=new Category();
category.set_id(id[i]);// setting Id
category.set_name(categoryName[i]);// setting category name
listData.add(category);
}
final ListView listview_category = (ListView) findViewById(R.id.listviewCategory);
listview_category.setAdapter(new CategoryListAdapter(this, listData ));
}
}
CategoryListAdapter.java
public class CategoryListAdapter extends BaseAdapter {
private ArrayList listData;
private LayoutInflater layoutInflater;
ArrayList table_cart = new ArrayList();
private static final String TAG = "CategoryListAdapter";
public CategoryListAdapter(Context aContext, ArrayList<Category> listData) {
this.listData = listData;
layoutInflater = LayoutInflater.from(aContext);
}
#Override
public int getCount() {
return listData.size();
}
#Override
public Object getItem(int position) {
return listData.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
final CategoryListAdapter.ViewHolder holder;
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.listview_category, null);
holder = new CategoryListAdapter.ViewHolder();
holder.btnCategory = (Button) convertView.findViewById(R.id.btnCategory);
convertView.setTag(holder);
} else {
holder = (CategoryListAdapter.ViewHolder) convertView.getTag();
}
holder.btnCategory.setText(listData.get(position).get_name());
holder.btnCategory.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// getting product id
int product_id = listData.get(position).getID();
Log.e(TAG, "product_id: " + product_id);
// now you can get category name as well
String category_name = listData.get(position).get_name();
Log.e(TAG, "category_name: " + category_name);
// now adding product id in to table_cart
table_cart.add(listData.get(position).getID());
}
});
return convertView;
}
static class ViewHolder {
Button btnCategory;
}
}
Category.java
public class Category {
private int _id;
private String _name;
public int getID() {
return this._id;
}
public void setID(int id) {
this._id = id;
}
public String get_name() {
return this._name;
}
public void set_name(String name) {
this._name = name;
}
public void set_id(int _id) {
this._id = _id;
}
}
there is no need to change layouts
Add on click listener for category button, add grid view in fragment and open fragment on button click.
holder.btnCategory.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
ProductFragment nextFrag= new ProductFragment();
this.getFragmentManager().beginTransaction()
.replace(R.id.Layout_container, nextFrag,TAG_FRAGMENT)
.commit();
}
});

how to develop navigation view inside sub navigation view with multiple selection in android?

I am new in Android. I am developing one app in android, Minimum API level is 15 and Maximum API level is 23.
I want like this, and another thing is multiple selection item in sub navigation. When any item is selected from parent navigation view, child navigation view will be open, as shown in image. I search on google but not getting answer. I see this and other so many stack overflow answer but not getting. please if some one help then it's very appreciate.Thanks in advance.
main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="#+id/lvList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorPrimary"/>
</LinearLayout>
this is my javafile
public class HomePageActivity extends AppCompatActivity
{
ListView lvList;
ArrayList<String> arrayList;
NavigationViewAdapter adapter;
ArrayList<RowObject> selectedItemArray;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_hope_page);
lvList = (ListView)findViewById(R.id.lvList);
setUpListView();
lvList.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
lvList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
for (int i = 0; i < selectedItemArray.size(); i++)
{
if (i == position){
selectedItemArray.get(position).setSelectedItem(true);
}else{
selectedItemArray.get(i).setSelectedItem(false);
}
}
adapter.notifyDataSetChanged();
}
});
}
private void setUpListView()
{
arrayList = new ArrayList<>();
selectedItemArray = new ArrayList<>();
for (int i = 0; i < 20; i++)
{
arrayList.add("Item "+(i+1));
selectedItemArray.add(new RowObject(i, false));
}
adapter = new NavigationViewAdapter(HomePageActivity.this, arrayList, selectedItemArray);
if (adapter != null)
{
lvList.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
}
}
This is my adapter
public class NavigationViewAdapter extends BaseAdapter
{
Activity activity;
View itemView;
private LayoutInflater inflater;
private ViewHolder viewHolder;
ArrayList<String> arrayList;
ArrayList<RowObject> selectedItemArray;
public NavigationViewAdapter(Activity activity, ArrayList<String> arrayList, ArrayList<RowObject> selectedItemArray)
{
this.activity = activity;
this.arrayList = arrayList;
this.selectedItemArray = selectedItemArray;
inflater = (LayoutInflater)this.activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return arrayList.size();
}
#Override
public Object getItem(int position) {
return arrayList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent)
{
try
{
itemView = convertView;
if (convertView == null){
itemView = inflater.from(parent.getContext()).inflate(R.layout.main_activity_item, parent, false);
viewHolder = new ViewHolder();
//if this is first time then inflate view
viewHolder.itemName = (TextView)itemView.findViewById(R.id.itemName);
itemView.setTag(viewHolder);
}else{
viewHolder = (ViewHolder)itemView.getTag();
}
//set Data from ArrayList
viewHolder.itemName.setText(arrayList.get(position));
if (selectedItemArray.get(position).isSelectedItem()){
viewHolder.itemName.setBackgroundColor(activity.getResources().getColor(R.color.colorPrimaryDark));
}else{
viewHolder.itemName.setBackgroundColor(activity.getResources().getColor(R.color.colorPrimary));
}
notifyDataSetChanged();
return itemView;
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
public class ViewHolder
{
TextView itemName;
}
}
this is my RowObject.java
public class RowObject
{
public int position;
boolean isSelectedItem;
public RowObject(int position, boolean isSelectedItem) {
this.position = position;
this.isSelectedItem = isSelectedItem;
}
public int getPosition() {
return position;
}
public void setPosition(int position) {
this.position = position;
}
public boolean isSelectedItem() {
return isSelectedItem;
}
public void setSelectedItem(boolean isSelectedItem) {
this.isSelectedItem = isSelectedItem;
}
}
I think this type of layout is not provided by android but you can fixed using your logic. I think you need to change your xml file, because your listview width is match_parent so your whole screen filled and your second sub menu is not display.Please change that or fix as per your requirement. Your main xml file.
main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical">
<ListView
android:id="#+id/lvList"
android:layout_width="100dp"
android:layout_height="match_parent"
android:background="#color/colorPrimary"/>
<ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/lvList"
android:layout_toEndOf="#+id/lvList">
<LinearLayout
android:id="#+id/llItemContainer"
android:layout_width="200dp"
android:layout_height="50dp"
android:orientation="vertical"
android:background="#color/input_login_hint">
</LinearLayout>
</ScrollView>
</RelativeLayout>
</LinearLayout>
And add one method in your listview onItemClickListener(). Please see my code.
java file.
public class NavigationActivity extends AppCompatActivity
{
ListView lvList;
LinearLayout llItemContainer;
ArrayList<String> arrayList;
NavigationViewAdapter adapter;
ArrayList<RowObject> selectedItemArray;
ArrayList<String> selectedSecondItem;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.navigation_activity);
lvList = (ListView)findViewById(R.id.lvList);
setUpListView();
lvList.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
llItemContainer = (LinearLayout)findViewById(R.id.llItemContainer);
lvList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
for (int i = 0; i < selectedItemArray.size(); i++)
{
if (i == position){
selectedItemArray.get(position).setSelectedItem(true);
}else{
selectedItemArray.get(i).setSelectedItem(false);
}
}
adapter.notifyDataSetChanged();
//here you can pass your sub view item array
generateSubView(position);
}
});
}
private void setUpListView()
{
arrayList = new ArrayList<>();
selectedItemArray = new ArrayList<>();
for (int i = 0; i < 20; i++)
{
arrayList.add("Item "+(i+1));
selectedItemArray.add(new RowObject(i, false));
}
adapter = new NavigationViewAdapter(NavigationActivity.this, arrayList, selectedItemArray);
if (adapter != null)
{
lvList.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
}
private void generateSubView(int position)
{
try
{
selectedSecondItem = new ArrayList<>();
llItemContainer.removeAllViews();
for (int i = 0; i <= position; i++)
{
final TextView rowText = new TextView(NavigationActivity.this);
TableRow.LayoutParams paramsExample = new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT,
147,2.0f);
rowText.setId(i);
rowText.setBackgroundColor(getResources().getColor(R.color.colorPrimary));
rowText.setGravity(Gravity.CENTER_VERTICAL);
rowText.setTextColor(getResources().getColor(android.R.color.white));
paramsExample.setMargins(3, 3, 3, 3);
rowText.setPadding(25, 25, 25, 25);
rowText.setTextSize(18);
rowText.setText("SecondItem " + i);
rowText.setLayoutParams(paramsExample);
rowText.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
rowText.setBackgroundColor(getResources().getColor(R.color.colorAccent));
selectedSecondItem.add(rowText.getText().toString());
}
});
llItemContainer.addView(rowText);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
you get the selected item from sub navigation view in selectedSecondItem arraylist.
Android Studio > New > Activity > Master/Detail Flow
Google docs link
OR
Stackoverflow answer

How to select only part of a listview based on different requirements by the user?

I am trying to develop an android mobile application whereby i am required to display part of a listviews which has at least 100 items.
Now i,being the admin of a college,i has listed 100 subjects to be taught.(all to be listed in a listview.All of the subjects have a point and in order for a strudent to apply for this course he/she need to have exact of higher points.An indicative sample is below:
English:24
Spanish:16
MAths:28
Science:26
French:16
Management:22
Law:30
Asian Language:10
Now the student needs to enter his/her point and based(EXACT OR LOWER POINT)on that, he/she get the list of subjects he/she is eligible to apply for.
E.g Enter your points:24
the output in the listview should give the following:
French:16
Management:22
English:24
Asian Language:10
I tried this but am stuck and could not complete the codes:
Course.java
public class Course {
private String name;
private int points;
public Course(String name, int points) {
this.name = name;
this.points = points;
}
public String getName() {
return name;
}
public int getPoints() {
return points;
}
#Override
public String toString() {
return getName();
}
}
Course[] courses = new Course[]{
new Course("Medicine", 30),
new Course("Physics", 28),
new Course("Math", 24),
new Course("English", 20)
};
Button searchButton = (Button) findViewById(R.id.btn_search);
searchButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
List<Course> courseList = new ArrayList<Course>(Arrays.asList(courses));
// initialize the adapter with courseList... //
// this code inside the Button's onClick
int points = Integer.parseInt(editText.getText().toString());
for (Course c : courses) {
if (c.getPoints() <= points) {
adapter.add(c);
}
}
course.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:layout_width="0dp"
android:layout_weight="1"
android:maxLines="1"
android:inputType="number"
android:layout_height="wrap_content"
android:hint="Enter your points:"
android:id="#+id/editText"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Search"
android:id="#+id/btn_search"/>
</LinearLayout>
<ListView
android:id="#+id/courseNames"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
My solution as below -
MainActivity
public class MainActivity extends AppCompatActivity {
ListView myList;
EditText edtSearch;
Button btnSearch;
listAdapter adapter;
ArrayList<Course> alSearchCourses;
Course[] courses;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myList = (ListView) findViewById(R.id.myList);
edtSearch = (EditText) findViewById(R.id.edtSearch);
btnSearch = (Button) findViewById(R.id.btnSearch);
courses = new Course[]{
new Course("Medicine", 30),
new Course("Physics", 28),
new Course("Math", 24),
new Course("English", 20)
};
adapter = new listAdapter(this, courses);
myList.setAdapter(adapter);
edtSearch.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (count == 0) {
adapter = new listAdapter(MainActivity.this, courses);
myList.setAdapter(adapter);
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
btnSearch.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
alSearchCourses = new ArrayList<>();
int points = Integer.parseInt(edtSearch.getText().toString());
for (int i = 0; i < courses.length; i++) {
Course c2 = courses[i];
if (c2.getPoints() <= points) {
alSearchCourses.add(c2);
}
}
Course searchCourses [] = new Course[alSearchCourses.size()];
searchCourses = alSearchCourses.toArray(searchCourses);
adapter = new listAdapter(MainActivity.this, searchCourses);
myList.setAdapter(adapter);
}
});
}
}
listAdapter
public class listAdapter extends BaseAdapter {
Context context;
Course[] courses;
LayoutInflater inflater;
public listAdapter(Context context, Course[] courses) {
this.context = context;
this.courses = courses;
inflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return courses.length;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null){
convertView = inflater.inflate(R.layout.list_item_layout, null);
}
TextView txtCourse = (TextView) convertView.findViewById(R.id.txtCourse);
txtCourse.setText(courses[position].getName() + "-" + courses[position].getPoints());
return convertView;
}
}
Hope it helps :)

Android OnClickListener not working with custom adapter

I've made a custom adapter for a ListView in order to display a String and an ImageButton within the same row. A row is generated every time the add button is clicked. The string is taken from the EditText field, while the ImageButton bin_button is allocated dinamically. Everything works fine except I can't make the bin_buttons fire an OnClick event.
I've tried several solutions. Here bin_button_listener is generated outside the add_button OnClickListener and then set. I've also tried to set listeners with a new OnClickListener every time a new bin_button was created.
Here some code:
Row layout list_string_button_layout.xml:
<TextView
android:id="#+id/list_item_string"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="8dp"
android:paddingEnd="0dp"
android:paddingTop="8dp"
android:textSize="18sp"
android:textStyle="bold"/>
<ImageButton
android:id="#+id/delete_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="10dp"
android:paddingEnd="5dp"
android:background="#00ffffff"
android:src="#drawable/ic_delete_black_18dp"
android:layout_alignBottom="#+id/list_item_string"
android:layout_alignParentEnd="true"
android:focusableInTouchMode="true"
/>
</RelativeLayout>
Activity layout activity_search.xml:
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/ingredient_text_input"
android:hint="#string/start_typing_ingredient"
android:layout_marginTop="52dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
/>
<Button
style="#style/Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/add_button"
android:backgroundTint="#color/colorPrimaryLight"
android:id="#+id/add_button"
android:layout_alignTop="#+id/ingredient_text_input"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"/>
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/ingredients_view"
android:layout_above="#+id/search_button"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="#+id/add_button" />
</RelativeLayout>
Custom Adapter IngredientBinAdapter:
public class IngredientBinAdapter extends BaseAdapter {
private Context context = null;
private List<HashMap<String,ImageButton>> items = new ArrayList<>();
public IngredientBinAdapter(Context context, ArrayList<HashMap<String,ImageButton>> items){
this.context=context;
this.items=items;
}
#Override
public int getCount() {
return items.size();
}
#Override
public Object getItem(int position) {
return items.get(position);
}
#Override
public long getItemId(int position) {
return getItem(position).hashCode();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null)
convertView = LayoutInflater.from(context).inflate(R.layout.list_string_button_layout,null);
HashMap<String,ImageButton> item = (HashMap<String,ImageButton>) getItem(position);
TextView string = (TextView) convertView.findViewById(R.id.list_item_string);
String key=(String) item.keySet().toArray()[0];
string.setText(key);
item.get(key).setImageResource(R.drawable.ic_delete_black_18dp);
return convertView;
}
}
Activity:
public class SearchActivity extends AppCompatActivity{
//getting resources and allocating variables
Button add_button = null;
Button search_button = null;
EditText insert_ingredient = null;
ListView ingredient_list_view = null;
ArrayList<HashMap<String,ImageButton>> ingredient_list = new ArrayList<>();
IngredientBinAdapter list_adapter = new IngredientBinAdapter(this,ingredient_list);
ArrayList<String> ingredients_utils = new ArrayList<>();
View.OnClickListener bin_button_listener = new View.OnClickListener() {
#Override
public void onClick(View v) {
System.out.println("BIN_BUTTON CLICKED");
ImageButton clicked_button = (ImageButton) v;
for(Iterator<HashMap<String,ImageButton>> i = ingredient_list.iterator(); i.hasNext(); ){
HashMap<String,ImageButton> temp= i.next();
if(temp.values().toArray()[0].equals(clicked_button))
ingredient_list.remove(temp);
}
list_adapter.notifyDataSetChanged();
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
}
#Override
protected void onStart(){
super.onStart();
add_button = (Button) findViewById(R.id.add_button);
search_button = (Button) findViewById(R.id.search_button2);
insert_ingredient = (EditText) findViewById(R.id.ingredient_text_input);
ingredient_list_view = (ListView) findViewById(R.id.ingredients_view);
ingredient_list_view.setAdapter(list_adapter);
//add_button listener
add_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String current_ingredient_string = insert_ingredient.getText().toString().trim();
if (!current_ingredient_string.isEmpty() && !ingredients_utils.contains(current_ingredient_string)) {
HashMap<String, ImageButton> temp = new HashMap<String, ImageButton>();
ImageButton temp_bin_button = new ImageButton(SearchActivity.this);
temp_bin_button.setOnClickListener(bin_button_listener);
temp.put(current_ingredient_string, temp_bin_button);
ingredient_list.add(temp);
list_adapter.notifyDataSetChanged();
}
ingredients_utils.add(insert_ingredient.getText().toString().trim());
insert_ingredient.getText().clear();
}
});
}
}
first of all
u should move your logic to onCreate() see: Difference between onCreate() and onStart()?
second
u should in your method in adapter :
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// 1. inflate view
// 2. find button
// 3. assign here listener to bin button
// i advice to use convert view pattern
}
some hints :
create data object describing row item
public class BinRow {
private String _someString;
private Drawable _imageDrawable; // (or resource id name)
public String getString() {
return _someString;
}
public Drawable getImage() {
return _imageDrawable;
}
public BinRow(String someText, Drawable imageDrawable) {
_someText = someText;
_imageDrawable = imageDrawable;
}
}
here u have adapter example ( u need adjust Album - to your BinRow & layout for row & convert view items in view holder ) - this should show you idea how adapter works :
public class AlbumAdapter extends BaseAdapter implements IListAdapter<Album> {
private List<Album> _albums;
private Context _context;
private LayoutInflater _layoutInflater;
static class ViewHolder {
ImageView imageView;
TextView albumName;
public ViewHolder(View v) {
imageView = (ImageView) v.findViewById(R.id.image);
albumName = (TextView) v.findViewById(R.id.tvAlbumName);
}
}
public AlbumAdapter(List<Album> albums) {
if(albums == null) {
_albums = new ArrasyList<>();
} else {
_albums = albums;
}
}
#Override
public int getCount() {
return _albums.size();
}
#Override
public Album getItem(int position) {
return _albums.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, final ViewGroup parent) {
final Album album = getItem(position);
if (_context == null) {
_context = parent.getContext();
}
if (_layoutInflater == null) {
_layoutInflater = LayoutInflater.from(_context);
}
View _view = convertView;
ViewHolder viewHolder;
if (_view == null) {
_view = _layoutInflater.inflate(R.layout.album_item_layout, parent, false);
viewHolder = new ViewHolder(_view);
_view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) _view.getTag();
}
viewHolder.albumName.setText(album.getAlbumDescription());
// here u can set: image to image view & listener to image
// image view could be a button
viewHolder.imageView.setOnClickListener(View.OnClickListener);
return _view;
}
#Override
public void add(Album listElement) {
_albums.add(listElement);
}
#Override
public void addAll(List<Album> listOfElements) {
_albums.addAll(listOfElements);
}
#Override
public void clear() {
_albums.clear();
}
#Override
public void remove(Album listElement) {
_albums.remove(listElement);
}
}
public interface IListAdapter<T> {
void add(T listElement);
void addAll(List<T> listOfElements);
void clear();
void remove(T listElement);
}
above interface serves as helper for adapter list methods

Categories

Resources