I have a Custom Listview that it is updated from a EditText component in a dialog. I have the custom row, the adapter class and the custom dialog all working but I can't seem to trigger the code in the adatper class that would add the text from the edit text control to the list. Here is my activity code, let me know if you want the adapter code. It worked before I added the custom row and adapter to the list :(
Symptom of problem: emailAdapter.notifyDataSetChanged(); does nothing
public class InvitePlayers_Activity extends Activity {
ListViewAdapter emailAdapter = null;
ImageView imgView_mail;
ImageView imgView_confirm;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE); //remove title bar
setContentView(R.layout.activity_inviteplayers);
//Generate list View from ArrayList
displayListView();
}
private void displayListView() {
//assign controls
final ListView listView = (ListView) findViewById(R.id.listView_invitePlayers);
imgView_mail = (ImageView)findViewById(R.id.imgView_mail);
//Test data
ArrayList<String> inviteNew = new ArrayList<String>();
final ArrayList<ArrayList<String>> inviteList = new ArrayList<ArrayList<String>>();
emailAdapter = new ListViewAdapter(this,inviteList);
listView.setAdapter(emailAdapter);
// Assign adapter to ListView
listView.setTextFilterEnabled(true);
//Edit listeners
imgView_mail.setOnClickListener(new View.OnClickListener() {
public void onClick(View view)
{
//variables
final String enteredMail = "testListViewEntry";
final ArrayList<ArrayList<String>> inviteList = new ArrayList<ArrayList<String>>();
ArrayList<String> invite = new ArrayList<String>();
invite.add(0, enteredMail);//add first email
invite.add(1,"icon_invitestatussent.png"); //add first status icon
inviteList.add(invite);
emailAdapter.notifyDataSetChanged();
listView.setAdapter(emailAdapter);
}
});
}
}
Adapter code as requested
public class ListViewAdapter extends BaseAdapter {
private Activity context;
ArrayList<ArrayList<String>> inviteDetails = new ArrayList<ArrayList<String>>();
public ListViewAdapter(Activity context, ArrayList<ArrayList<String>> inviteDetails ) {
this.inviteDetails = inviteDetails;
this.context = context;
}
#Override
public int getCount() {
return inviteDetails.size();
}
#Override
public Object getItem(int i) {
return inviteDetails.get(i).get(0);
}
#Override
public long getItemId(int i) {
return i;
}
public View getView(int position, View view, ViewGroup parent){
//Inflater
LayoutInflater inflater = context.getLayoutInflater();
//get row view
if (view == null) {
LayoutInflater mInflater = (LayoutInflater)
context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
view = mInflater.inflate(R.layout.list_item_email, null);
}
//assign controls
final TextView textView_playerEmail = (TextView) view.findViewById(R.id.textView_playerEmail);
ImageView imgView_inviteStatus = (ImageView) view.findViewById(R.id.imgView_inviteStatus);
//Assign control values that are dynamic
textView_playerEmail.setText(inviteDetails.get(position).get(0));
imgView_inviteStatus.setImageResource(R.drawable.icon_invitestatussent);
return view;
}
#Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
}
}
Custom row xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:textSize="16sp"
android:id="#+id/textView_playerEmail"
android:textColor="#color/white"
android:text="item1">
</TextView>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imgView_inviteStatus" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imgView_remove"
android:src="#drawable/btn_cancel" />
</LinearLayout>
The activity layout
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="20"
android:background="#color/yellow"
android:layout_margin="20dp"
android:padding="5dp">
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:weightSum="1"
android:gravity="left|center">
<ImageView
android:layout_width="45dp"
android:layout_height="34dp"
android:id="#+id/imgView_mail"
android:src="#drawable/btn_mail"
android:layout_weight="0.22"
android:padding="3dp" />
</LinearLayout>
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/listView_invitePlayers"
android:layout_gravity="center_horizontal" />
</LinearLayout>
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:id="#+id/btn_confirm"
android:src="#drawable/btn_confirm"
android:clickable="false"
android:adjustViewBounds="true"
android:layout_gravity="center_horizontal"
android:padding="2dp"
android:layout_weight="1" />
</LinearLayout>
</FrameLayout>
Well, for what we discussed, you wanted something like this:
When you want to make a custom ListView, you have to write your own adapter. In this particular case I'm subclassing the BaseAdapter class.
This custom adapter will take hold of my data model, and will inflate the data to my ListView rows.
First, I'll create the XML of my custom row. You can see the code below.
item_mail.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Test text"
android:id="#+id/tv_mail"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/iv_icon"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:src="#android:drawable/ic_menu_report_image" />
</RelativeLayout>
Here I've created a row that displays a text and an image.
Now, I'll create my custom adapter to handle this XML. As you can see below.
MailAdapter.java
public class MailAdapter extends BaseAdapter {
private static final String LOG_TAG = MailAdapter.class.getSimpleName();
private Context context_;
private ArrayList<ArrayList<String>> mailitems;
public MailAdapter(Context context, ArrayList<ArrayList<String>> mailitems) {
this.context_ = context;
this.mailitems = mailitems;
}
#Override
public int getCount() {
return mailitems.size();
}
#Override
public Object getItem(int position) {
return mailitems.get(position).get(0);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater)
context_.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.item_mail, null);
}
TextView tv_mail = (TextView) convertView.findViewById(R.id.tv_mail);
ImageView iv_icon = (ImageView) convertView.findViewById(R.id.iv_icon);
String mail = mailitems.get(position).get(0);
String icon = mailitems.get(position).get(1);
Log.d(LOG_TAG,"Mail: " + mail + " mail_icon: " + icon);
tv_mail.setText(mail);
// iv_icon.setImageURI(); Here you can do whatever logic you want to update your image, using URI's, ID's, or something else.
return convertView;
}
}
Ok. Now we have everything to make this work. In your Activity class, do something like that:
activity_main.xml
<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" android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin" tools:context=".MainActivity">
<TextView
android:text="#string/hello_world"
android:id="#+id/tv_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/tv_header">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Add mail"
android:id="#+id/button"
android:layout_gravity="center" />
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/listView" />
</LinearLayout>
</RelativeLayout>
MainActivity.java
public class MainActivity extends ActionBarActivity {
private int numMail = 1; // Dummy int to create my items with different numbers.
private MailAdapter mailAdapter; // Your custom adapter.
private ArrayList<ArrayList<String>> mailItems; // This is going to be your data structure, everytime you change it, call the notifyDataSetChanged() method.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button bt = (Button) findViewById(R.id.button);
ListView lv_mail = (ListView) findViewById(R.id.listView);
mailItems = new ArrayList<>();
mailAdapter = new MailAdapter(this,mailItems);
lv_mail.setAdapter(mailAdapter);
bt.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
addItem(); // The method I'm using to insert the item. Look for it below.
}
});
}
// Here I'm creating a new ArrayList, and appending it to my 'mailItems' Array. After that, I'm notifying the adapter that my data changed.
private void addItem() {
ArrayList<String> mail = new ArrayList<>();
mail.add(0,"mail " + numMail++);
mail.add(1,"path_to_image"); // Depending on what you want to do, put your path, URI, or whatever other way you want to store that image data.
mailItems.add(mail); // Inserting the data on the ArrayList.
mailAdapter.notifyDataSetChanged(); // Notifying the adapter that my ArrayList was modified.
}
}
This should do the trick.
I guess your problem was that you weren't updating the same ArrayList that was in your custom adapter. That's why when you called notifyDataSetChanged()nothing happened, I mean. You were creating a new ArrayList, which wasn't the same that was in your adapter. So here's what I did... I've made the ArrayList global, and then I've used it in my custom adapter constructor. After that, when the user triggers the onClick() method of my button, I'm inserting some new data on my global Array, and then I'm notifying the adapter that the data changed.
You can read a little more about that here and I've found a similar question here, which you can read as well.
Edit: Another related question, which might be an interesting read.
Related
I have a listView with some items now I want to change the background color or item text color by click on a separate button which IS NOT on the list . How can I do that in my android app?
This is my main activity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
arrayAdapter = new SubArrayAdapter(this, dataItemList);
ListView lv = findViewById(R.id.mylist);
lv.setAdapter(arrayAdapter);
ImageButton btn_check = findViewById(R.id.button_checkout);
btn_check.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// how can I access the list items within this click-handler method
});
List Item Layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/listitems"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="5dp">
<ImageView
android:id="#+id/yes_image"
android:layout_width="30dp"
android:layout_height="30dp"
android:paddingRight="5dp"
android:visibility="invisible"
/>
<ImageView
android:id="#+id/no_image"
android:layout_width="30dp"
android:layout_height="30dp"
android:paddingRight="5dp"
android:visibility="invisible"
/>
<TextView
android:id="#+id/paragraph_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#id/yes_image"
android:layout_toRightOf="#id/yes_image"
android:textColor="#color/paragraph_items_colro"
android:textSize="16sp"
android:textStyle="normal" />
</RelativeLayout>
Activity_main xml layout file:
android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/main_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textAlignment="center"
android:textDirection="ltr"
tools:context=".MainActivity">
<ListView
android:id="#+id/mylist"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:background="#android:color/transparent"
android:divider="#color/colorAccent"
android:dividerHeight="1dp"
android:listSelector="#0f0"
app:layout_constraintStart_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</ListView>
<LinearLayout
android:id="#+id/btn_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="horizontal"
app:layout_constraintTop_toBottomOf="#id/mylist">
<ImageButton
android:id="#+id/button_checkout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:background="#drawable/checkout_9"
android:src="#drawable/checkout_9"
app:layout_constraintTop_toBottomOf="#id/mylist"
tools:layout_editor_absoluteX="106dp" />
</LinearLayout>
</android.support.constraint.ConstraintLayout>
And I have myown adapter class that in the getview() method I populated the list items
this inner class is located in mainactivity:
private class SubArrayAdapter extends ArrayAdapter<DataItem> {
private List<DataItem> items;
private Context context;
public SubArrayAdapter(#NonNull Context context, #NonNull List<DataItem>
items) {
super(context, R.layout.listitems, items);
this.items = items;
this.context = context;
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull
ViewGroup parent) {
DataItem dataitem1 = items.get(position);
LayoutInflater inflater = (LayoutInflater)
context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.listitems, null);
TextView tv = (TextView)
view.findViewById(R.id.paragraph_description);
tv.setText(dataitem1.getDescription());
tv.setTag(position + 100);
ImageView yes_iv = view.findViewById(R.id.yes_image);
int yes_res = context.getResources().getIdentifier("yes",
"drawable", getPackageName());
yes_iv.setImageResource(yes_res);
yes_iv.setTag(position + 200);
//yes_iv.setVisibility(View.VISIBLE);
ImageView no_iv = view.findViewById(R.id.no_image);
int no_res = context.getResources().getIdentifier("no", "drawable",
getPackageName());
no_iv.setImageResource(no_res);
no_iv.setTag(position + 300);
return view;
}
}
}
I've noticed You have set android:listSelector for ListView in Your activity_main.xml - which was giving You an ability to change item's background on single click.
So I decided to check out how it works in ListView class.
I've looked at source code of ListView and searched for phrase selector. There was the line:
} else if (mAction == STATE_REQUEST_FOCUS) {
final int childIndex = mPosition - mFirstPosition;
final View child = getChildAt(childIndex);
if (child != null) {
child.requestFocus();
}
mAction = -1;
}
final View child = getChildAt(childIndex);
Following these steps - I knew solution for Your question problem. Here it is:
ImageButton imageButton = findViewById(R.id.button_checkout);
imageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int hardCodedPoositionToSelect = 1;
View childAt = listView.getChildAt(hardCodedPoositionToSelect);
if (childAt != null) {
//change background
childAt.setBackgroundColor(Color.RED);
//change textView color of current view
TextView paragraphDescription = childAt.findViewById(R.id.paragraph_description);
paragraphDescription.setTextColor(Color.MAGENTA);
}
}
});
You can see I am calling getChildAt() on listView to obtain current item's view basing on item's position from hardCodedPoositionToSelect.
I want to display 3 fields from the database, but I do not know about simple_list_item_1
SQLiteDatabase db = dbcenter.getReadableDatabase();
cursor = db.rawQuery("SELECT * FROM TABLE", null);
daftar = new String[cursor.getCount()];
cursor.moveToFirst();
for (int cc = 0; cc < cursor.getCount(); cc++) {
cursor.moveToPosition(cc);
daftar[cc] = cursor.getString(1).toString();
}
ListView01 = (ListView) view.findViewById(R.id.listView1);
ListView01.setAdapter(new ArrayAdapter(getActivity(), android.R.layout.simple_list_item_1, daftar));
ListView01.setSelected(true);
In the above view is the code displays the data from the table, but only one field appears.
Can you give me an example, to replace it into modified list_item with 3 <TextView> with java code
you can create a custom list view with 3 text view
now custom_list_view layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/name"
android:text="#string/name"
android:textSize="20sp"
android:layout_marginTop="19dp"
android:layout_alignParentTop="true"
android:layout_toLeftOf="#+id/price"
android:layout_toStartOf="#+id/price"
android:layout_marginRight="30dp"
android:layout_marginEnd="30dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/price"
android:text="Price"
android:textSize="20sp"
android:layout_alignBaseline="#+id/name"
android:layout_alignBottom="#+id/name"
android:layout_centerHorizontal="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/stock"
android:text="Stock"
android:textSize="20sp"
android:layout_alignBaseline="#+id/price"
android:layout_alignBottom="#+id/price"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginRight="81dp"
android:layout_marginEnd="81dp"/>
</RelativeLayout>
Create List View in layout , i created in mainactivity layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.pro.salman.customlistview.MainActivity">
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/list_item"/>
</RelativeLayout>
Custom List View Class
public class CustomListView extends BaseAdapter {
private ArrayList<HashMap<String,String>> list;
private LayoutInflater mLayoutInflater;
private Context mContext;
public CustomListView(ArrayList<HashMap<String,String>> list,Context c) {
this.list = list;
this.mContext = c;
mLayoutInflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return list.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 view = mLayoutInflater.inflate(R.layout.custom_list_view,parent,false);
Holder h = new Holder();
// set id's
h.name = (TextView)(view.findViewById(R.id.name));
h.price = (TextView)(view.findViewById(R.id.price));
h.stock = (TextView)(view.findViewById(R.id.stock));
HashMap<String,String> hashMap = new HashMap<>();
hashMap = list.get(position);
h.name.setText(hashMap.get("nameKey"));
h.price.setText(hashMap.get("priceKey"));
h.stock.setText(hashMap.get("stockKey"));
return view;
}
private class Holder
{
TextView name;
TextView price;
TextView stock;
}
}
And Now in mainactivity class
public class MainActivity extends AppCompatActivity {
private ListView mListView;
private ArrayList<HashMap<String,String>> mArrayList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mArrayList = new ArrayList<HashMap<String, String>>();
for(int i =0;i<20;i++)
{
HashMap<String,String> mHashMap = new HashMap<>();
mHashMap.put("nameKey","name "+String.valueOf(i));
mHashMap.put("priceKey","price "+String.valueOf(i));
mHashMap.put("stockKey","stock "+String.valueOf(i));
mArrayList.add(mHashMap);
}
mListView = (ListView)(findViewById(R.id.list_item));
CustomListView customListView = new CustomListView(mArrayList,this);
mListView.setAdapter(customListView);
}
}
Result
When you call new ArrayAdapter(..., android.R.layout.simple_list_item_1, ...), you're telling the system to use android.R.layout.simple_list_item_1 for your data. If that doesn't work, there's really only one option: handle inflating and populating the view yourself. You'd do that by creating a custom subclass of ArrayAdapter and overriding onCreateView().
Official documentation: https://developer.android.com/reference/android/widget/ArrayAdapter.html
You may also customize what type of view is used for the data object in the collection. To customize what type of view is used for the data object, override getView(int, View, ViewGroup) and inflate a view resource.
create a xml named custom_layout like
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="16sp" >
</TextView>
Use like R.layout.custom_layout instead of android.R.layout.simple_list_item_1
I have a listview which uses a CursorAdapter to populate the listview. I want to allow users to choose multiple items and perform actions, such as delete items, on all of the selected items at the same time. I tried adding a CheckBox item to the layout xml of the item item_vocab.xml. The checkbox showed up beside each item, but I wasn't able to figure out how to keep track of the status of the checked items. I also tried adding setChoiceMode(ListView.CHOICE_MODE_MULTIPLE) instead but the checkbox didn't show up.
Here are some of my code:
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_alignParentRight="true"
android:layout_alignParentEnd="true"/>
<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"/>
</RelativeLayout>
activity_my_vocab.xml
<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="charlesli.com.personalvocabbuilder.io.MyVocabActivity">
<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>
MyVocabActivity.java
public class MyVocabActivity extends ActionBarActivity {
private VocabCursorAdapter mVocabAdapter;
private ListView mVocabListView;
private TextView mEmptyTextView;
private Cursor mCursor;
private String mSelectedVocab;
private CheckBox mCheckBox;
private VocabDbHelper mDbHelper = new VocabDbHelper(this);
private ArrayList<String> mCheckedItems = new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_vocab);
mVocabListView = (ListView) findViewById(R.id.mVocabList);
mEmptyTextView = (TextView) findViewById(android.R.id.empty);
mVocabListView.setEmptyView(mEmptyTextView);
mCursor = mDbHelper.getCursorMyVocab(mDbHelper);
mVocabAdapter = new VocabCursorAdapter(this, mCursor, 0);
mVocabListView.setAdapter(mVocabAdapter);
mVocabListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
mVocabListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
mSelectedVocab = (String) ((TextView) view.findViewById(R.id.vocabName)).getText();
editVocabAlertDialog(mSelectedVocab, view, position, id);
return true;
}
});
}
VocabCursorAdapter.java
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);
String vocab = cursor.getString(cursor.getColumnIndexOrThrow(VocabDbContract.DatabaseInfo.COLUMN_NAME_VOCAB));
String definition = cursor.getString(cursor.getColumnIndexOrThrow(VocabDbContract.DatabaseInfo.COLUMN_NAME_DEFINITION));
int level = cursor.getInt(cursor.getColumnIndexOrThrow(VocabDbContract.DatabaseInfo.COLUMN_NAME_LEVEL));
tvVocabName.setText(vocab);
tvVocabDefinition.setText(definition);
if (level == DIFFICULT) {
tvVocabLevel.setImageResource(R.drawable.level_bars_difficult);
}
else if (level == FAMILIAR) {
tvVocabLevel.setImageResource(R.drawable.level_bars_familiar);
}
else if (level == EASY) {
tvVocabLevel.setImageResource(R.drawable.level_bars_easy);
}
else if (level == PERFECT) {
tvVocabLevel.setImageResource(R.drawable.level_bars_perfect);
}
}
}
Please let me know if I need to provide further information.
You can use CustomListview for this, make another xml that have textview and checkbox and use that layout in your custom adapter class for populating list then it will work like you want. For example look this tutorial:
http://techlovejump.com/android-listview-with-checkbox/
I have been searching the internet on how to add modifiable text/string in a ListView using BaseAdapter but no luck thus far. This is what I want to do as shown below:
Item_1 $price1
Item_2 $price2
The format shown above is the template form i would like the listView to take. Item_1 and $price1 are in the first row while item_2 and $price2 are in the second row. I do not want a predefined list but a list where the user should be able to add an item along with its price and should be able to modify it accordingly.
Below is a section of my code that I'm trying to use in the ToDoAdapter extends BaseAdapter class:
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
CompleteListViewHolder viewHolder;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.list_layout, null);
viewHolder = new CompleteListViewHolder(v);
v.setTag(viewHolder);
} else {
viewHolder = (CompleteListViewHolder) v.getTag();
}
viewHolder.mTVItem.setText(mList.get(position));
viewHolder.mTvItem2.setText(mList.get(position));
return v;
}
}
class CompleteListViewHolder {
public TextView mTVItem, mTvItem2;
public CompleteListViewHolder(View base) {
mTVItem = (TextView) base.findViewById(R.id.listTV);
mTvItem2 = (TextView) base.findViewById(R.id.listTv2);
}
Main Activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_complete_list);
initViews();
mItems = new ArrayList<String>();
mListAdapter = new CompleteListAdapter(this, mItems);
mCompleteListView.setAdapter(mListAdapter);
}
private void initViews() {
mCompleteListView = (ListView) findViewById(R.id.completeList);
mAddItemToList = (Button) findViewById(R.id.addItemToList);
mAddItemToList.setOnClickListener(this);
}
private void addItemsToList() {
mListAdapter.notifyDataSetChanged();
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.addItemToList:
addItemsToList();
break;
}
}
XML Layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/listTV"
android:layout_width="142dp"
android:layout_height="60dp"
android:gravity="center_vertical"
android:text="Income"
android:textSize="42sp"
android:typeface="sans" />
<TextView
android:id="#+id/listTv2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/listTV"
android:layout_alignBottom="#+id/listTV"
android:layout_marginLeft="45dp"
android:layout_toRightOf="#+id/listTV"
android:text="Amount"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
XML Main Activity Layout:
<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=".CompleteListActivity" >
<ListView
android:id="#+id/completeList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_marginBottom="80dp" >
</ListView>
<Button
android:id="#+id/addItemToList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_margin="10dp"
android:text="#string/add_item" />
</RelativeLayout>
Any help is appreciated
Your button notifies the adapter that the data changed, but in fact the data did not change.
So what you need to do is to modify the adapters data first and then call notifyDataSetChanged()
i've a problem, i want an EditText above my ListView that performs a search in that ListView. Is it possible to do?
This is the Activity code:
public static class BirreChiareListView extends Main implements AdapterView.OnItemClickListener {
ListView list;
String [] birrechiare;
int [] images={R.drawable.ichnusa, R.drawable.ichnusa_speciale, R.drawable.ichnusa_cruda};
private MyAdapter adapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(birrechiare_listview);
Resources res=getResources();
birrechiare=res.getStringArray(R.array.birre_chiare);
list = (ListView)findViewById(R.id.listViewBirreChiare);
MyAdapter adapter = new MyAdapter(this,birrechiare, images);
list.setAdapter(adapter);
list.setOnItemClickListener(this);
}
#Override
public void onItemClick(AdapterView<?> adapter, View view, int position, long l) {
String item = adapter.getItemAtPosition(position).toString();
Toast.makeText(getApplicationContext(), "Hai selezionato: " + item, Toast.LENGTH_SHORT).show();
if (position == 0){
Intent gotoclassica = new Intent(BirreChiareListView.this,Ichnusa_Classica.class);
startActivity(gotoclassica);
}
if (position == 1){
Intent gotospeciale = new Intent(BirreChiareListView.this,Ichnusa_Speciale.class);
startActivity(gotospeciale);
}
if (position == 2){
Intent gotocruda = new Intent(BirreChiareListView.this,Ichnusa_Cruda.class);
startActivity(gotocruda);
}
}
}
static class MyAdapter extends ArrayAdapter<String> {
Context context;
int[] images;
String[] titleArray;
MyAdapter(Context c, String[] titles, int imgs []){
super (c, single_row, R.id.Titletxt, titles);
this.context = c;
this.images=imgs;
this.titleArray=titles;
}
#Override
public View getView (int position, View convertView, ViewGroup parent){
LayoutInflater inflater = (LayoutInflater)context.getSystemService(LAYOUT_INFLATER_SERVICE);
View row=inflater.inflate(single_row, parent,false);
ImageView myimage = (ImageView) row.findViewById(R.id.imageView);
TextView mytitle = (TextView) row.findViewById(R.id.Titletxt);
myimage.setImageResource(images[position]);
mytitle.setText(titleArray[position]);
return row;
}
}
Ok, this is the XML file of the ListView:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#drawable/background_listview">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Birre Chiare"
android:singleLine="false"
android:textColor="#FFFFFF"
android:gravity="center"/>
<EditText
android:id="#+id/search"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<requestFocus />
</EditText>
<ListView
android:id="#+id/listViewBirreChiare"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
</LinearLayout>
At the end, this is the single_row.xml file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:id="#+id/imageView"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:src="#drawable/ichnusa"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Large Text"
android:id="#+id/Titletxt"
android:layout_alignBottom="#+id/imageView"
android:layout_toRightOf="#+id/imageView"
android:layout_marginBottom="35dp"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
</RelativeLayout>
Yes this is definitely possible to do. Android provides a Filterable interface for ArrayAdapters. The interface provides a getFilter() method where you can hook into the filtering process.
When the text changes in your EditText, you call adapter.getFilter().filter("filterString"). The text changing behaviour for the EditText is done by using a TextWatcher on the EditText. This following tutorial, explains it in good detail:
http://www.survivingwithandroid.com/2012/10/android-listview-custom-filter-and.html
EDIT:
To implement the filterable interface, just do this in your ArrayAdapter:
static class MyAdapter extends ArrayAdapter<String> implements Filterable {
private Filter myFilter;
#Override
public Filter getFilter() {
if (myFilter == null)
myFilter = new MyFilter();
return myFilter;
}
}
where MyFilter is your own Filter class.