From this Activity i get text from textField and display it in a ListView.
Now i want to to add check box on every entry in a listView Cell and also like to know how to display more than one text in a single ListView Cell.
Help with code will be appreciated.
Here is my code ....
public class AfterRegister extends AppCompatActivity
{
ListView listView;
EditText editText;
Button insertItemButton;
ArrayList<String> arrayList = new ArrayList<String>();
ArrayAdapter<String> adapter;
CheckBox checkBox;
StoreRegistrationDataBase storeRegistrationDataBase;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_after_register);
storeRegistrationDataBase = new StoreRegistrationDataBase(this);
storeRegistrationDataBase = storeRegistrationDataBase.open();
checkBox = (CheckBox) findViewById(R.id.checkbox);
insertItemButton = (Button) findViewById(R.id.button4);
insertItemButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
editText = (EditText) findViewById(R.id.editText2);
listView = (ListView) findViewById(R.id.listView);
String getEditTextString = editText.getText().toString();
if(isAlphaNumeric(getEditTextString))
{
if(!getEditTextString.equals(""))
{
arrayList.add(getEditTextString);
adapter = new ArrayAdapter<String>(getBaseContext(), R.layout.text_view_layout, R.id.achView1, arrayList);
listView.setAdapter(adapter);
adapter.notifyDataSetChanged();
editText.setText("");
}
else
{
Toast.makeText(AfterRegister.this, "You can not insert empty field", Toast.LENGTH_SHORT).show();
}
}
else
{
Toast.makeText(AfterRegister.this, "Remove Space", Toast.LENGTH_SHORT).show();
}
}
});
listView.setOnTouchListener(new View.OnTouchListener()
{
#Override
public boolean onTouch(View v, MotionEvent event)
{
return false;
}
});
}
public boolean isAlphaNumeric(String s)
{
String pattern= "^[a-zA-Z0-9]*$";
if(s.matches(pattern))
{
return true;
}
return false;
}
}
You have to use a BaseAdapter and some Getter/Setter methods to add multiple texts/images/other UI elements in each item of your list view.
You have to implement multiple things to get this result. Here they are --
Create a Custom Layout for each item of your ListView.
listview_item_layout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/layout_textview1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:layout_marginRight="5dip"
android:textStyle="bold"/>
<TextView
android:id="#+id/layout_textview2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:layout_marginLeft="5dip"
android:textStyle="bold"/>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/checkbox"
android:text="Test"/>
</LinearLayout>
Create a custom class and add some Getter/Setter methods.
ListRowItem.java
public class ListRowItem implements Serializable{
String carrier,number;
public String getCarrier(){
return carrier;
}
public String getNumber(){
return number;
}
public void setCarrier(String ba_carrier){
carrier = ba_carrier;
}
public void setNumber(String ba_number){
number = ba_number;
}
}
Create a custom class and extend the BaseAdapter class.
public class MyBaseAdapter extends BaseAdapter {
public Context ba_context;
public ArrayList<ListRowItem> listitem = new ArrayList<>();
public LayoutInflater inflater;
ListRowItem currentlistitem;
public MyBaseAdapter(Context ma_context, ArrayList<ListRowItem> ma_listitem) {
super();
this.ba_context = ma_context;
this.listitem = ma_listitem;
inflater = (LayoutInflater) ba_context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return this.listitem.size();
}
#Override
public Object getItem(int position) {
return this.listitem.get(position);
}
#Override
public long getItemId(int position) {
return (long) position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
if (convertView == null)
vi = inflater.inflate(R.layout.listview_item_layout, parent, false);
TextView carrier = (TextView) vi.findViewById(R.id.layout_textview1);
TextView number = (TextView) vi.findViewById(R.id.layout_textview2);
currentlistitem = listitem.get(position);
String str_carrier = currentlistitem.getCarrier();
String str_number = currentlistitem.getNumber();
carrier.setText(str_carrier);
number.setText(str_number);
return vi;
}
}
Finally, populate your ArrayList and set the Adapter in your MainActivity.
ArrayList<ListRowItem> listitem = new ArrayList<>();
Context context = TestActivity.this;
MyBaseAdapter baseAdapter;
ListRowItem lr = new ListRowItem();
lr.setNumber(number);
lr.setCarrier(carrier);
listitem.add(lr);
baseAdapter = new MyBaseAdapter(context,listitem);
setContentView(R.layout.activity_test);
listView = (ListView) findViewById(R.id.list_view);
listView.setAdapter(baseAdapter);
Hope this helps!!
Related
I am trying to manipulate a View in an ArrayList adapter. I am using the following code:
for (int i = 0; i < listView.getCount(); i++){
TextView busDestTextView = (TextView) busAdapter.getView(i, null, null).findViewById(R.id.busDestinations);
TextView busNumberTextView = (TextView) busAdapter.getView(i, null, null).findViewById(R.id.busNumber);
if (dataSnapshot.getKey().equals(busDestTextView.getText().toString())){
busNumberTextView.setText(dataSnapshot.getValue().toString());
break;
}
}
The listView consist of horizontal Views having two text views busDestinations and busNumber.
The setText() method is not changing the text in desired way. It seems to have no effect on the busNumberTextView.
EDIT: As other users suggested, these are the codes I have right now.
MainActivity.java
package com.example.busnotifier;
import ...;
public class MainActivity extends AppCompatActivity {
private FirebaseDatabase mFirebaseInstance;
private DatabaseReference mFirebaseDatabase;
private FirebaseMessaging mFirebaseMessaging;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ArrayList<Bus> buses = new ArrayList<Bus>();
buses.add(new Bus("Dev_Guradiya~Industry_House~Palasia", 0));
buses.add(new Bus("Bhavarkua-V", 0));
buses.add(new Bus("Boys_hostel~teen_imli~Khajarana", 0));
buses.add(new Bus("Khativala~Rani_Sati~Agnibaan~Khajrana", 0));
buses.add(new Bus("Kalani_Naga", 0));
buses.add(new Bus("Khandwa_naka~Shalimaar~Scheme_54", 0));
buses.add(new Bus("tilak_nagar", 0));
buses.add(new Bus("Rani_Sati~Agnibaan~Khajrana~Rani_sati", 0));
buses.add(new Bus("Industry_House~Rani_Sati~Agnibaan~Khajrana", 0));
buses.add(new Bus("Agnibaan~Khajarana~Rani_Sati", 0));
buses.add(new Bus("PardesipuraVijaynagar", 0));
buses.add(new Bus("Sai_Mandir~VijayNagar", 0));
BusAdapter busAdapter= new BusAdapter(this, buses);
// Get a reference to the ListView, and attach the adapter to the listView.
final ListView listView = (ListView) findViewById(R.id.busListView);
listView.setAdapter(busAdapter);
mFirebaseInstance = FirebaseDatabase.getInstance();
mFirebaseInstance.getReference("Buses").addChildEventListener(new ChildEventListener() {
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
for (int i = 0; i < listView.getCount(); i++){
if (dataSnapshot.getKey().equals(buses.get(i).getDestinations())){
TextView busNumberTextView = (TextView) listView.getChildAt(i).findViewById(R.id.busNumber);
busNumberTextView.setText(dataSnapshot.getValue().toString());
}
}
Toast.makeText(getApplicationContext(), ""+dataSnapshot.getKey(), Toast.LENGTH_SHORT).show();
}
});
}
}
BusAdapter.java
package com.example.busnotifier;
import ....;
public class BusAdapter extends ArrayAdapter<Bus> {
private FirebaseDatabase mFirebaseDatabase = FirebaseDatabase.getInstance();
private DatabaseReference mDatabaseReference = mFirebaseDatabase.getReference("Buses");
public BusAdapter(Activity context, ArrayList<Bus> buses){
super(context, 0, buses);
}
public View getView(int position, View convertView, ViewGroup parent){
View busListItemView = convertView;
if(busListItemView == null) {
busListItemView = LayoutInflater.from(getContext()).inflate(R.layout.list_item, parent, false);
}
// TextView for the Bus number
Bus currentBus = getItem(position);
final TextView busNumberTextView = (TextView) busListItemView.findViewById(R.id.busNumber);
busNumberTextView.setText(String.valueOf(currentBus.getBusNumber()));
// Used EraserRegular font for the bus-stop names
Typeface typeFace = Typeface.createFromAsset(getContext().getAssets(), "fonts/KGSecondChancesSolid.ttf");
busNumberTextView.setTypeface(typeFace);
// TextView for the destinations of the corresponding bus-number
final Button destinationsTextView = (Button) busListItemView.findViewById(R.id.busDestinations);
destinationsTextView.setText(currentBus.getDestinations());
destinationsTextView.setTypeface(typeFace);
destinationsTextView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
/*If the user clicks on a button it will change color and subscribe
the user to corresponding Topic of the FireBase*/
Toast.makeText(getContext(), "Subscribed to: "+destinationsTextView.getText(), Toast.LENGTH_LONG).show();
int color = ContextCompat.getColor(getContext(), R.color.buttonClicked);
destinationsTextView.setBackgroundColor(color);
FirebaseMessaging.getInstance().subscribeToTopic(String.valueOf(destinationsTextView.getText().toString()));
mDatabaseReference.child(destinationsTextView.getText().toString()).setValue(Integer.parseInt(busNumberTextView.getText().toString()));
Log.d(">>>>", "onClick: "+destinationsTextView.getText().toString()+"/"+busNumberTextView.getText().toString());
}
});
return busListItemView;
}
}
ListItem.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="match_parent"
android:padding="5dp"
android:gravity="center"
android:background="#414141"
android:id="#+id/busListEntry"
android:layout_height="wrap_content">
<Button
android:layout_width="0dp"
android:id="#+id/busDestinations"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:layout_weight="5"
android:background="#color/buttonColor"
android:textColor="#fff"
android:paddingLeft="5dp"
android:textAllCaps="false"
android:layout_marginRight="10dp"
tools:text="aksjfdkaskdfalsasfasfasfasdasf aslkjfaksjfkjaks dkajsdf asdfajsdfjalksd fasjflkajsdasf asjfkajsdklfjas"
android:textSize="17sp"/>
<TextView
android:layout_width="wrap_content"
android:id="#+id/busNumber"
android:textStyle="bold"
android:textSize="17sp"
android:textColor="#fff"
android:layout_height="wrap_content"
android:gravity="center"
android:background="#drawable/round_background"
tools:text="1"/>
Bus.java
package com.example.busnotifier;
public class Bus {
private int busNumber;
private String destinations;
public Bus(String destinations, int busNumber) {
this.busNumber = busNumber;
this.destinations = destinations;
}
public int getBusNumber() {
return busNumber;
}
public String getDestinations() {
return destinations;
}
public void setDestinations(String destinations) {
this.destinations = destinations;
}
public void setBusNumber(int busNumber) {
this.busNumber = busNumber;
}
}
You have 2 approaches. 1 you can use listview with onItemClickListener. The alternative is to implement OnItemSelectedListener in your bus array adapter.
I'm a little rusty with android so here is what I recommend:
Get your list view and adapter setup:
mAdapter = new BusAdapter();
mListView = (ListView) findViewById(R.layout.my_listview);
mListView.setAdapter(mAdapter);
Add item click listener to your list view:
mListView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView parent, View view,int position, long id) {
mAdapter.onBusItemSelected(position);
Log("Selected item at position " + position);
mAdapter.notifyDataSetChanged()
}
});
In your adapter, add a public function called "onBusItemSelected(int position)" and update your data structures. For example, have a boolean variable labeled "selected". By default it is false.
...
void onItemSelected(int position) {
getItem(position).selected = true;
}
Last, your custom ArrayAdapter needs to update the getView() item to look for the new variable and update the text color based on that variable.
public View getView(int position, View convertView, ViewGroup parent)
...
if (bus.selected) {
holder.textView.setTextColor(RED);
} else {
holder.textView.setTextColor(BLACK);
}
...
}
I think you put ViewGroup null in busAdapter.getView(i, null, null). You can read: https://developer.android.com/reference/android/widget/Adapter.html#getView(int, android.view.View, android.view.ViewGroup)
I have a basket icon with count notification on it in actionbar for showing number of goods in shopping basket. also I have a custom view containing a button for add goods to shopping basket. I want that when I click on button (in custom view) notification count on basket icon increases. I use this function in main activity to update notification count but notification does not update.
public static void updateCountBasket(final int number , int id , View view ,Context context) {
if (view.findViewById(id) == null)
return;
TextView t = (TextView)view.findViewById(id);
String dd = t.getText().toString();
((Activity) context).runOnUiThread(new Runnable() {
#Override
public void run() {
if (number == 0)
t.setVisibility(View.INVISIBLE);
else {
t.setVisibility(View.VISIBLE);
t.setText(Integer.toString(number));
}
}
});
}
but when I use non static of that function in main activity with simple button on click, it works fine. but I can't call non static function in base adapter too :( . I checked line by line of the function in static mode all ids are right and it set text too but nothing change or get error!!. please help me to change textview as notification of basket in menubar from base adapter when button in custom view clicks. thanks
I have this base adapter for my custom view list:
public class Goods_ImageAdapter extends BaseAdapter {
private Context context;
private final JSONArray Goods;
private Bagde bagde;
public Goods_ImageAdapter(Context context , JSONArray Goods) {
this.context = context;
this.Goods = Goods;
bagde = Bagde.getInstance();
}
#Override
public int getCount() {
return Goods.length();
}
#Override
public Object getItem(int arg0) {
return null;
}
#Override
public long getItemId(int arg0) {
return 0;
}
public static String doubleToStringNoDecimal(double d) {
DecimalFormat formatter = (DecimalFormat) NumberFormat.getInstance(Locale.US);;
formatter .applyPattern("#,###");
return formatter.format(d);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View gridView;
final View bagde_c;
if (convertView == null) {
gridView = new View(context);
gridView = inflater.inflate(R.layout.goodsitem, null);
bagde_c = inflater.inflate(R.layout.badge_counter, null);
try {
TextView goods_textview_Name = (TextView) gridView.findViewById(R.id.goods_textview_Name);
goods_textview_Name.setText(Goods.getJSONObject(position).getString("Name"));
TextView goods_textview_Price = (TextView) gridView.findViewById(R.id.goods_textview_Price);
goods_textview_Price.setText(Goods.getJSONObject(position).getString("Price"));
} catch (JSONException e) {
e.printStackTrace();
}
try {
ImageView goods_imageview = (ImageView) gridView.findViewById(R.id.goods_imageview);
new ImageDownloader(goods_imageview).execute("http://IP/" + Goods.getJSONObject(position).getString("ImageFileName"));
} catch (JSONException e) {
e.printStackTrace();
}
final TextView goods_textview_bagdecounter = (TextView) gridView.findViewById(R.id.goods_textview_bagdecounter);
ImageView goods_buy_plus = (ImageView) gridView.findViewById(R.id.goods_buy_button_plus);
try {
goods_buy_plus.setTag(Goods.getJSONObject(position));
} catch (JSONException e) {
e.printStackTrace();
}
goods_buy_plus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
((Activity) context).runOnUiThread(new Runnable() {
#Override
public void run() {
String bagde_counter_text = goods_textview_bagdecounter.getText().toString();
goods_textview_bagdecounter.setText(String.valueOf(Integer.parseInt(bagde_counter_text) + 1));
}
});
com.???.????.Goods_Activity.updateCountBasket(a number for example,R.id.notif,inflater2.inflate(R.layout.badge_counter, null),context);
}
});
ImageView goods_buy_minus = (ImageView) gridView.findViewById(R.id.goods_buy_button_minus);
try {
goods_buy_minus.setTag(Goods.getJSONObject(position));
} catch (JSONException e) {
e.printStackTrace();
}
goods_buy_minus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
((Activity) context).runOnUiThread(new Runnable() {
#Override
public void run() {
String bagde_counter_text = goods_textview_bagdecounter.getText().toString();
if(Integer.parseInt(bagde_counter_text)> 0)
goods_textview_bagdecounter.setText(String.valueOf(Integer.parseInt(bagde_counter_text) - 1));
}
});
}
});
} else {
gridView = (View) convertView;
}
return gridView;
}
}
this is (basket with notification on action bar) badge_counter.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="#android:style/Widget.ActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:clickable="true"
android:gravity="center"
android:orientation="vertical">
<RelativeLayout
android:id="#+id/badge_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RelativeLayout
android:id="#+id/relative_layout_item_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:id="#+id/button"
android:layout_width="40dip"
android:layout_height="40dip"
android:background="#drawable/download" />
<TextView
android:id="#+id/notif"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:background="#android:drawable/ic_notification_overlay"
android:text="33"
android:textColor="#FFA"
android:textSize="12sp"
android:textStyle="bold" />
</RelativeLayout>
</RelativeLayout>
</RelativeLayout>
You can achieve this by using interface.
Add an interface in Adapter class
public interface AdapterCallBack
{
public void onChangeBadgeCount();
}
And in constructor, pass a reference to this interface.
public Goods_ImageAdapter(Context context , JSONArray Goods, AdapterCallBack adapterCallback)
{
this.context = context;
this.Goods = Goods;
this.adapterCallback = adapterCallback;
bagde = Bagde.getInstance();
}
And whenever you want to set badge count in ActionBar, just call adapterCallback.onChangeBadgeCount().
And implement this interface in MainActivity.
public class MainActivity implements Goods_ImageAdapter.AdapterCallBack
{
... some code
When your are initializing adapter, just pass this as a last parameter.
Example:
adapter = new Goods_ImageAdapter(this, Goods /* Json data */, this);
...
#override
public void onChangeBadgeCount()
{
// Change your badge count here
}
}
I am printing my array length size in ActionBar from Recycler adapter
((Show_request) mContext).getSupportActionBar().setTitle("Total Stone:- " + array.length());
Using this you can get ActionBar in RecyclerView adapter
((your activity name) context object).getSupportActionBar().setTitle("message"/or pass variable);
For my Android project, I have a listview which has a checkbox for every item. The data is loaded from an SQLite database by using a CursorAdapter class. However, whenever I scroll, the checkbox positions will get moved and get carried down to the next part of the listview. How can I fix this problem?
GIF of my CheckBox Problem
Here's my Cursor Adapter Class:
public class VocabCursorAdapter extends CursorAdapter {
private static final int DIFFICULT = 0;
private static final int FAMILIAR = 1;
private static final int EASY = 2;
private static final int PERFECT = 3;
public VocabCursorAdapter(Context context, Cursor c, int flags) {
super(context, c, 0);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.item_vocab, parent, false);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
// Find fields to populate in inflated template
TextView tvVocabName = (TextView) view.findViewById(R.id.vocabName);
TextView tvVocabDefinition = (TextView) view.findViewById(R.id.vocabDefinition);
ImageView tvVocabLevel = (ImageView) view.findViewById(R.id.vocabLevel);
// Extract properties from cursor
String vocab = cursor.getString(cursor.getColumnIndexOrThrow(VocabDbContract.COLUMN_NAME_VOCAB));
String definition = cursor.getString(cursor.getColumnIndexOrThrow(VocabDbContract.COLUMN_NAME_DEFINITION));
int level = cursor.getInt(cursor.getColumnIndexOrThrow(VocabDbContract.COLUMN_NAME_LEVEL));
// Populate fields with extracted properties
tvVocabName.setText(vocab);
tvVocabDefinition.setText(definition);
if (level == DIFFICULT) {
tvVocabLevel.setImageResource(R.drawable.level_bars_difficult);
tvVocabLevel.setTag(DIFFICULT);
}
else if (level == FAMILIAR) {
tvVocabLevel.setImageResource(R.drawable.level_bars_familiar);
tvVocabLevel.setTag(FAMILIAR);
}
else if (level == EASY) {
tvVocabLevel.setImageResource(R.drawable.level_bars_easy);
tvVocabLevel.setTag(EASY);
}
else if (level == PERFECT) {
tvVocabLevel.setImageResource(R.drawable.level_bars_perfect);
tvVocabLevel.setTag(PERFECT);
}
}
And here's my list item xml, item_vocab.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:longClickable="true">
<ImageView
android:layout_width="36sp"
android:layout_height="36sp"
android:id="#+id/vocabLevel"
android:layout_gravity="right"
android:src="#drawable/level_bars"
android:scaleType="fitXY"
android:contentDescription="#string/vocab_level"
android:layout_centerVertical="true"
android:layout_toLeftOf="#+id/editCheckbox"
android:layout_toStartOf="#+id/editCheckbox"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Large Text"
android:id="#+id/vocabName"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_toLeftOf="#+id/vocabLevel"
android:layout_toStartOf="#+id/vocabLevel"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="Small Text"
android:id="#+id/vocabDefinition"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_toLeftOf="#+id/vocabLevel"
android:layout_toStartOf="#+id/vocabLevel"
android:layout_below="#id/vocabName"/>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/editCheckbox"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"/>
</RelativeLayout>
And here's my xml which contains a listview
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".controller.MyVocab"
android:paddingLeft="5dp">
<ListView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/mVocabList"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/empty_text_view"
android:id="#android:id/empty"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"/>
</RelativeLayout>
I have looked at a lot of different solutions on StackOverflow, but I wasn't able to successfully do it in my own app. For an example, this post has a similar problem, but its solution used getView and I had trouble understanding how to implement it with newView and bindView instead.
And some other solutions might be examples where a cursoradapter is not involved. Any help is much appreciated, thanks a lot!
Edit #1: After incorporating Phan's changes, the checkbox states get resets to false rather than keeping its states when I scroll the listview (See ).
Reason : ListView re-uses the views.
Solution :
class VocabCursorAdapter extends CursorAdapter {
List<Integer> selectedItemsPositions;//to store all selected items position
public VocabCursorAdapter(Context context, Cursor c,int flags) {
super(context, c,0);
selectedItemsPositions = new ArrayList<>();
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup viewGroup) {
View view = LayoutInflater.from(context).inflate(R.layout.item_vocab, viewGroup, false);
CheckBox box = (CheckBox) view.findViewById(R.id.editCheckbox);
box.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
int position = (int) compoundButton.getTag();
if (b) {
//check whether its already selected or not
if (!selectedItemsPositions.contains(position))
selectedItemsPositions.add(position);
} else {
//remove position if unchecked checked item
selectedItemsPositions.remove((Object) position);
}
}
});
return view;
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
//your other stuff
CheckBox box = (CheckBox) view.findViewById(R.id.editCheckbox);
box.setTag(cursor.getPosition());
if (selectedItemsPositions.contains(cursor.getPosition()))
box.setChecked(true);
else
box.setChecked(false);
}
}
Try this
public class VocabCursorAdapter extends CursorAdapter {
private ArrayList<Boolean> itemChecked = new ArrayList<Boolean>(); // array list for store state of each checkbox
public VocabCursorAdapter(Context context, Cursor c, int flags) {
for (int i = 0; i < c.getCount(); i++) { // c.getCount() return total number of your Cursor
itemChecked.add(i, false); // initializes all items value with false
}
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
...
final int position = cursor.getPosition(); // get position by cursor
CheckBox checkBox = (CheckBox) view.findViewById(R.id.editCheckbox);
checkBox.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (itemChecked.get(position) == true) { // if current checkbox is checked, when you click -> change it to false
itemChecked.set(position, false);
} else {
itemChecked.set(position, true);
}
}
});
checkBox.setChecked(itemChecked.get(position)); // set the checkbox state base on arraylist object state
Log.i("In VocabCursorAdapter","position: "+position+" - checkbox state: "+itemChecked.get(position));
}
}
public class ObservationselectattributeFragment extends Fragment {
DatabaseHandler mDBHandler;
ListView mListView;
SimpleCursorAdapter mSCA;
Cursor mCsr;
ArrayList<String> attributeItems = new ArrayList<>();
public ObservationselectattributeFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Inflate the layout for this fragment
View view1=inflater.inflate(R.layout.fragment_observationselectattribute, container, false);
//Bundle bundle2 = getArguments();
Bundle bundle1 = getArguments();
final int firsttext= bundle1.getInt("TotalCount");
final String selectedtreatment= bundle1.getString("SelectedTreatment");
Toast.makeText(getActivity(),"value \n"+firsttext+"\n"+"treatment \n"+selectedtreatment, Toast.LENGTH_SHORT).show();
// Toast.makeText(getActivity(),"SelectedTreatment \n"+selectedtreatment, Toast.LENGTH_SHORT).show();
mListView = (ListView)view1.findViewById(R.id.lv001);
mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
Button addattribute = (Button)view1.findViewById(R.id.addattribute);
addattribute.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String items1="";
Integer tcount1=0;
for(String item1:attributeItems){
items1+="-"+item1+"\n";
tcount1++;
}
Toast.makeText(getActivity(),"you have selected \n"+items1,Toast.LENGTH_LONG).show();
Toast.makeText(getActivity(),"you have selected \n"+tcount1,Toast.LENGTH_LONG).show();
/*FragmentTransaction fr= getFragmentManager().beginTransaction();
fr.replace(R.id.main_container, new ShowObservationDataRecordingFragment()).addToBackStack("ObservationselectattributeFragment");
fr.commit();*/
Bundle bundle = new Bundle();
bundle.putInt("TotalCount2",firsttext);
bundle.putInt("TotalCount1", tcount1);
bundle.putString("SelectedTreatment", selectedtreatment);
Fragment showobservationdatarecordingfragment = new ShowObservationDataRecordingFragment();
showobservationdatarecordingfragment.setArguments(bundle);
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.main_container, showobservationdatarecordingfragment).addToBackStack("ObservationselectattributeFragment").commit();
}
});
mDBHandler = new DatabaseHandler(this.getActivity());
mCsr = mDBHandler.getAllRecords();
// Prepare a list of the columns to get the data from, for the ListViewt
String[] columns_to_get_data_from = new String[]{
DatabaseHandler.KEY_IDS,
DatabaseHandler.KEY_NAMES,
DatabaseHandler.KEY_FNAME,
DatabaseHandler.KEY_MONAME,
DatabaseHandler.KEY_SNAME
};
// Prepare a list of the Views into which to place the data
int[] itemviews_to_place_data_in = new int[]{
R.id.euserid,
R.id.eusername,
R.id.efname,
R.id.emoname,
R.id.esname
};
// get and instance of SimpleCursorAdapter
mSCA = new SimpleCursorAdapter(getActivity(),
R.layout.listviewitem_record,
mCsr,
columns_to_get_data_from,
itemviews_to_place_data_in,
0);
// Save the ListView state (= includes scroll position) as a Parceble
Parcelable state = mListView.onSaveInstanceState();
// get and instance of SimpleCursorAdapter the listviewitem_record layout
mListView.setAdapter(mSCA);
// Restore previous state (including selected item index and scroll position)
mListView.onRestoreInstanceState(state);
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String attributeItem1 = ((TextView)view.findViewById(R.id.euserid)).getText().toString();
String attributeItem2 = ((TextView)view.findViewById(R.id.eusername)).getText().toString();
String attributeItem3 = ((TextView)view.findViewById(R.id.efname)).getText().toString();
String attributeItem4 = ((TextView)view.findViewById(R.id.emoname)).getText().toString();
String attributeItem5 = ((TextView)view.findViewById(R.id.esname)).getText().toString();
String attributeItem = attributeItem1 + attributeItem2 + attributeItem3 + attributeItem4 + attributeItem5;
// CheckedTextView box = (CheckedTextView) view.findViewById(R.id.record_checkbox);
// box.setChecked(true);
CheckedTextView checkedTextView = (CheckedTextView) view.findViewById(R.id.record_checkbox);
if(checkedTextView.isChecked()) {
checkedTextView.setChecked(false);
} else {
checkedTextView.setChecked(true);
}
if(attributeItems.contains(attributeItem)){
attributeItems.remove(attributeItem);//uncheck item
}
else
{
attributeItems.add(attributeItem);
}
Toast.makeText(getActivity(), "Item1 = " + attributeItem1 +"\n"+ "Item2 ="+attributeItem2 +"\n"+"Item3 ="+attributeItem3+"\n"+"Item4 ="+attributeItem4+"\n"+"Item5 ="+attributeItem5, Toast.LENGTH_SHORT).show();
}
});
((HomeActivity) getActivity())
.setActionBarTitle("Select Attribute");
return view1;
}
}
I am trying to create a custom listview with a checkbox and a string list of "observations" retrieved from my sqlite database. The idea is that when I click on the "retrieve" button, all checked items are shown in a toast message.
I can populate the listview through my customadapter just fine, but it doesnt seem to recognise the status of each checkbox, as no toast messages are shown, regardless of whether they are checked.
Please can someone show me where I am going wrong?
Here is my custom listview xm that I have called list_o:
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:descendantFocusability="blocksDescendants"
android:id="#+id/obsgrid">
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/chkbx"
android:layout_row="0"
android:layout_column="0" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Large Text"
android:id="#+id/obs"
android:layout_row="0"
android:layout_column="1" />
Here is my custom adapter:
class CustomAdObs extends ArrayAdapter<String> {
private String [] observation;
private Boolean [] checked;
private Context context;
public CustomAdObs(Context context, String[] observation) {
super(context, R.layout.list_o, observation);
this.observation = observation;
this.checked = checked;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater siteInflater = LayoutInflater.from(getContext());
View customView = siteInflater.inflate(R.layout.list_o, parent, false);
TextView observationTV = (TextView) customView.findViewById(R.id.obs);
CheckBox checkCB = (CheckBox) customView.findViewById(R.id.chkbx);
checkCB.setTag(Integer.valueOf(position));
observationTV.setText(observation[position]);
checkCB.setChecked(checked[position]);
return customView;
}
}
Finally here is my activity:
public class selobs extends Activity {
List< List<String> > listArray = new ArrayList< List<String> >();
List<String> array1 = new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode. setThreadPolicy(policy);
setContentView(R.layout.activity_selobs);
final Button retrieve= (Button) findViewById(R.id.btnret);
final EditText txtob = (EditText) findViewById(R.id.editText23);
filladapter();
retrieve.setOnClickListener(
new View.OnClickListener() {
public void onClick(View view) {
ListView obsListView = (ListView) findViewById(R.id.obsList);
View v;
for (int i = 0; i < obsListView.getCount(); i++) {
v = obsListView.getAdapter().getView(i, null, null);
CheckBox check = (CheckBox) v.findViewById(R.id.chkbx);
TextView obsItem = (TextView) v.findViewById(R.id.obs);
if (check.isChecked()) {
String p = obsItem.getText().toString();
Toast.makeText(selobs.this, p, Toast.LENGTH_LONG).show();
}
}
}
}
);
}
public void filladapter(){
myDBhandler1 dbHandler;
dbHandler = new myDBhandler1(selobs.this, null, null, 1);
listArray = dbHandler.databaseToStringObs();
List array1 = listArray.get(0);
String[] observ = (String[]) array1.toArray(new String[0]);
Boolean[] checked = new Boolean[0];
Arrays.fill(checked, Boolean.FALSE);
final ListAdapter ObsAdapter = new CustomAdObs(this, observ, checked);
final ListView obsListView = (ListView) findViewById(R.id.obsList);
obsListView.setAdapter(ObsAdapter);
obsListView.setOnItemClickListener(
new AdapterView.OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String item = String.valueOf(parent.getItemAtPosition(position));
Toast.makeText(selobs.this, item, Toast.LENGTH_LONG).show();
TextView txtobs = (TextView) findViewById(R.id.editText23);
txtobs.setText(item);
}
}
);
}
}
your constructor
public CustomAdObs(Context context, String[] observation) {//here the Boolean[] checked ->is messing
super(context, R.layout.list_o, observation);
this.observation = observation;
this.checked = checked;
}
so you replace it with this
public CustomAdObs(Context context, String[] observation, Boolean[] checked) {
super(context, R.layout.list_o, observation);
this.observation = observation;
this.checked = checked;
}
why ?
because you call it like this
new CustomAdObs(this, observ, checked);
while you have just the 2 params in your constructor(Context context,String[] observation)
I have a list view in left of the screen and on click of the item i want to update a text on the right half of the screen, what i want to do here is that to move the clicked item in center of the listview. Like if the item is on top and i click on it it automatically moves to the center of the list view, how I can do this? Any kind of help will be appreciated.
I have a listview in which 7 items are visible and on startup 4th item will be selected as this is in center of the visible items in listview and if there are n items and whichever item is selected by user will be in center of the visible items in listview. Like i have 10 items and on start 4th is selected and when user selects the 3rd item, nth item from listview should come to index zero and and 3rd will come to position 4. Similarly for every other selected item? Can any one provide a code snippet for this?
Change items order in ListView source Array and then call notifyDataSetChanged() in ListView Adapter
EDIT: Code sample
public class ListAdapter extends BaseAdapter{
private Activity activity;
private ArrayList<ListRowObject> listItems;
public ListAdapter(Activity activity){
this.activity = activity;
listItems = new ArrayList<ListRowObject>();
}
public void addItem(ListRowObject item){
listItems.add(item);
notifyDataSetChanged();
}
public void addItems(ArrayList<ListRowObject> items){
listItems = items;
notifyDataSetChanged();
}
public void clear(){
listItems = null;
listItems = new ArrayList<ListRowObject>();
notifyDataSetChanged();
}
#Override
public int getCount() {
return listItems.size();
}
#Override
public Object getItem(int position) {
return listItems.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup viewGroup) {
ViewHolder holder;
if(convertView == null){
holder = new ViewHolder();
convertView = activity.getLayoutInflater().inflate(R.layout.list_row, null);
holder.text = (TextView) convertView.findViewById(R.id.text);
holder.bgLayout = (LinearLayout) convertView.findViewById(R.id.bgLayout);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
ListRowObject row = listItems.get(position);
if(row.isSelected())
holder.bgLayout.setBackgroundColor(Color.GRAY);
else
holder.bgLayout.setBackgroundColor(Color.WHITE);
holder.text.setText(row.getText());
return convertView;
}
}
//--------
public class ListRowObject {
private String text;
private int positionInList;
private boolean isSelected;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public int getPositionInList() {
return positionInList;
}
public void setPositionInList(int positionInList) {
this.positionInList = positionInList;
}
public boolean isSelected() {
return isSelected;
}
public void setSelected(boolean selected) {
isSelected = selected;
}
}
//------
public class Main extends Activity {
private ListView listView;
private ListAdapter adapter;
private Activity activity;
private ArrayList<ListRowObject> items;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
activity = this;
initializeFormViews();
initializeOnClickEvents();
fillList();
}
private void initializeFormViews(){
listView = (ListView) findViewById(R.id.listView);
}
private void initializeOnClickEvents(){
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
Toast.makeText(activity, "Pressed " +position, Toast.LENGTH_SHORT).show();
// unselect all rows
for(ListRowObject item : items){
item.setSelected(false);
}
int first = adapterView.getFirstVisiblePosition();
int last = adapterView.getLastVisiblePosition();
int centerPosition = (first + last) / 2;
// change bg for centerPosition row
adapterView.getChildAt(centerPosition).findViewById(R.id.bgLayout).setBackgroundColor(Color.GRAY);
changeItems(position, centerPosition);
}
});
}
private void changeItems(int pressedPosition, int centerPosition){
ListRowObject centerRow = items.get(centerPosition);
ListRowObject pressedRow = items.get(pressedPosition);
pressedRow.setSelected(true);
centerRow.setSelected(false);
items.remove(centerPosition);
items.add(centerPosition, pressedRow);
items.remove(pressedPosition);
items.add(pressedPosition, centerRow);
adapter.clear();
adapter.addItems(items);
}
private void fillList(){
adapter = new ListAdapter(activity);
items = new ArrayList<ListRowObject>();
items = getItems();
for(ListRowObject item : items){
adapter.addItem(item);
}
listView.setAdapter(adapter);
}
private ArrayList<ListRowObject> getItems(){
ArrayList<ListRowObject> result = new ArrayList<ListRowObject>();
for(int i = 0; i < 15; i++){
ListRowObject object = new ListRowObject();
object.setPositionInList(i);
object.setText("Item #" + i);
if(i != 4)
object.setSelected(false);
else
object.setSelected(true);
result.add(object);
}
return result;
}
}
//------
public class ViewHolder {
public TextView text;
public LinearLayout bgLayout;
}
list_row.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="50dp"
android:id="#+id/bgLayout">
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:id="#+id/text"
android:textColor="#000000"
android:textSize="24dp"
android:gravity="center"/>
</LinearLayout>
main.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:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/listView"/>
</LinearLayout>
when you create ArrayAdapter for your listview you send a ListArray to it.when you want change content .you only change this listArray then when click your item you can change ListArray and call notifyDataSetChanged(); method your adapter.