I am writing the basic task management application. I am using base adapter to work with ListView. I wonder how I can remove (a few) checked values from the list? And how I can remove only one value with long click?
if this posible with my adapter? I tried a few options but nothing worked.
Here is my code.
<?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="match_parent"
>
<Button
android:id="#+id/btn1"
android:layout_width="50dp"
android:layout_height="40dp"
android:layout_alignParentRight="true"
android:text="\u2713"
android:background="#drawable/add_btn"
android:onClick="knopka2"/>
<EditText
android:id="#+id/input"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="#id/btn1"
android:hint="put your task here"/>
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/listView"
android:divider="#drawable/deriver"
android:layout_below="#+id/input"
android:layout_centerHorizontal="true"
android:choiceMode="multipleChoice" />
<TextView
android:id="#+id/ttl"
android:layout_below="#id/listView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="#+id/tryClear"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/ttl"
android:onClick="tryClear"
/>
</RelativeLayout>
This is my Activity:
public class Trird extends AppCompatActivity {
Button btn;
EditText input4;
TextView ttl;
ListView list;
public static ArrayList<String> taskList = new ArrayList<String>();
SparseBooleanArray sparseBooleanArray;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.third);
input4 = (EditText) findViewById(R.id.input);
btn = (Button) findViewById(R.id.btn1);
list = (ListView) findViewById(R.id.listView);
ttl = (TextView)findViewById(R.id.ttl);
}
public String[] putToArray() {
String ag = input4.getText().toString().trim();
if (ag.length() != 0) {
taskList.add(ag);
input4.setText("");
}
String[] abc = taskList.toArray(new String[taskList.size()]);
return abc;
}
public void knopka2(View v) {
final String[] ListViewItems = putToArray(); //
list = (ListView) findViewById(R.id.listView);
list.setAdapter(new MyAdapter(ListViewItems, this));
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View tv, int i, long id) {
///tv.setBackgroundColor(Color.YELLOW);
///ttl.setText("selected: " + list.getAdapter().getItem(i));
sparseBooleanArray = list.getCheckedItemPositions();
String ValueHolder = "";
int a = 0;
while (a < sparseBooleanArray.size()) {
if (sparseBooleanArray.valueAt(a)) {
ValueHolder += ListViewItems[sparseBooleanArray.keyAt(a)] + ",";
}
a++;
}
ValueHolder = ValueHolder.replaceAll("(,)*$", "");
Toast.makeText(Trird.this, "ListView Selected Values = " + ValueHolder, Toast.LENGTH_LONG).show();
if(ValueHolder!=null){
taskList.remove(ValueHolder);
}
}
});
}
}
This is my adapter:
public class MyAdapter extends BaseAdapter {
private final Context context;//Context for view creation
private final String[] data;//raw data
public MyAdapter(String[] data, Context context){
this.data=data;
this.context=context;
}
//how many views to create
public int getCount() {
return data.length;
}
//item by index (position)
public Object getItem(int i) {
return data[i];
}
//ID => index of given item
public long getItemId(int i) {
return i;
}
//called .getCount() times - for each View of item in data
public View getView(int i, View recycleView, ViewGroup parent) {
if(recycleView==null)recycleView = LayoutInflater.from(context).inflate(R.layout.item,null);
((TextView)recycleView).setText(data[i]);//show relevant text in reused view
return recycleView;
}
}
And this is how looks like item in ListView.
<CheckedTextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="24sp"
android:drawableRight="?android:attr/listChoiceIndicatorMultiple"
/>
The problem is that you are trying removing item using the ListView remove methode.
Just remove the selected item from the list using the remove() method of your Adapter.
A possible way to do that would be:
CheckedTextView checkedText= baseAdapter.getItem([POSITION OF THE SELECTED ITEM]);
baseAdapter.remove(checkedText);
baseAdapter.notifyDataSetChanged();
put this code inside the wanted button click and there you go.
Related
I want to create a listview that displays the same clickable icon several times. I tried many ways, including a custom adapter with layout inflater but failed... At this point my ListView displays numbers instead of the icon. Can you help me please? here is my code
public class UserSelectionActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {
static ArrayList<Integer> arrayOfIcons = new ArrayList<Integer>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_selection);
arrayOfIcons.clear();
for (int i=0; i<3; i++) {arrayOfIcons.add(R.drawable.edit);}
ArrayAdapter<Integer> adapter2 = new ArrayAdapter<Integer>(this, android.R.layout.simple_list_item_1, arrayOfIcons);
ListView listView2 = (ListView) findViewById(R.id.usersListView2);
listView2.setAdapter(adapter2);
listView2.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//TODO
}
});
}
}
I don't do anything in onResume method, that's why I didn't share it
And my 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">
<ListView
android:id="#+id/usersListView2"
android:layout_width="80dp"
android:layout_height="450dp"
android:layout_alignParentEnd="true"
android:paddingTop="4dip"
android:paddingBottom="3dip" />
</RelativeLayout>
Hy, I suggest you to create a custom adapter:
1) create your list_item:
In res -> layout create a new file named list_item.xml. It contains only one imageView inserted into a ConstraintLayout:
<?xml version="1.0" encoding="utf-8"?>
<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:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/imageViewIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
app:srcCompat="#mipmap/ic_launcher" />
2) In your activity_main.xml you have to inser your listView:
<?xml version="1.0" encoding="utf-8"?>
<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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ListView
android:id="#+id/listViewIcon"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
3) Now you have to create a new class call, for example, IconAdapter, where you create your custom adapter:
public class IconAdapter extends BaseAdapter {
Context context;
List<Integer> iconIDList;
/**
*
* #param context = activity context
* #param iconIDList = list with icon's id
*/
public IconAdapter(Context context, List<Integer> iconIDList) {
this.context = context;
this.iconIDList = iconIDList;
}
#Override
public int getCount() {
//return the size of my list
return iconIDList.size();
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(int i, View convertView, ViewGroup viewGroup) {
//inflate my view
if (convertView == null) {
LayoutInflater inflater;
inflater = LayoutInflater.from(context);
convertView = inflater.inflate(R.layout.list_item, null);
}
//istantiate my imageView
ImageView imageView = convertView.findViewById(R.id.imageViewIcon);
//set imageView's icon
imageView.setImageResource(iconIDList.get(i));
//return my view
return convertView;
}
}
4) Now in your MainActivity, put all together:D
public class MainActivity extends AppCompatActivity {
List<Integer> iconIDList;
IconAdapter iconAdapter;
ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//istantiate my components
iconIDList = new ArrayList<>();
listView = findViewById(R.id.listViewIcon);
iconAdapter = new IconAdapter(this, iconIDList);
int myIcon = R.drawable.ic_launcher_background;
//populate the list with icon's id
for (int i = 0; i < 5; i++) {
iconIDList.add(myIcon);
}
//set my custom adapter to the listView
listView.setAdapter(iconAdapter);
//set clickListner to the elements of my listView
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
//i is the index of the clicked element
Toast.makeText(MainActivity.this, "Click on element n. " + i, Toast.LENGTH_SHORT).show();
}
});
}
}
I hope that can help you!!! Good job!! If you have a question, comment my answer!!
In your comment you ask me how to add one listener for the name (textView) clicked and one for the icon clicked.
1) modify your list_item.xml file. Now we can use:
a LinearLayout instead of ConstraintLayout;
a textView;
a ImageButton instead of ImageView.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="wrap_content"
android:orientation="horizontal"
android:descendantFocusability="blocksDescendants" > <!--this is very important to detect click-->
<TextView
android:id="#+id/textViewIcon"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3"
android:gravity="left|center"
android:text="TextView"
android:textSize="24sp" />
<ImageButton
android:id="#+id/imageButtonIcon"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="8dp"
android:layout_weight="1"
app:srcCompat="#mipmap/ic_launcher" />
</LinearLayout>
2) Is better if you create a class that contains your data. We can call this class IconData:
public class IconData {
int iconID;
String text;
//constructor
public IconData(int iconID, String text) {
this.iconID = iconID;
this.text = text;
}
//getter and setter
public int getIconID() {
return iconID;
}
public void setIconID(int iconID) {
this.iconID = iconID;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
3) Now we have to change our IconAdapter.
We'll add an Interface to detect clicks on the ImageButton;
We'll change the list's data type;
We'll instatiate the newest TextView and ImageButton:
//create custom adapter -> I extend my class using BaseAdapter
public class IconAdapter extends BaseAdapter {
//create an interface to comunicate the clicks on the imageButton
public interface MyIconAdapterInterface {
void setOnClickListnerMyImageButton (int position);
}
Context context;
//change the list's name and data type
List<IconData> iconIDTextList;
MyIconAdapterInterface myIconAdapterInterface;
/**
* #param context = activity context
* #param iconIDTextList = list with icon's id and text
* #param myIconAdapterInterface = the interface that mainActivity will implements
*/
public IconAdapter(Context context, List<IconData> iconIDTextList, MyIconAdapterInterface myIconAdapterInterface) {
this.context = context;
this.iconIDTextList = iconIDTextList;
this.myIconAdapterInterface = myIconAdapterInterface;
}
#Override
public int getCount() {
//return the size of my list
return iconIDTextList.size();
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(final int i, View convertView, ViewGroup viewGroup) {
//inflate my view
if (convertView == null) {
LayoutInflater inflater;
inflater = LayoutInflater.from(context);
convertView = inflater.inflate(R.layout.list_item, null);
}
//istantiate my imageView and textView
ImageButton imageButton = convertView.findViewById(R.id.imageButtonIcon);
TextView textView = convertView.findViewById(R.id.textViewIcon);
//set imageView's button
int image = iconIDTextList.get(i).getIconID();
imageButton.setImageResource(image);
//set text
String text = iconIDTextList.get(i).getText();
textView.setText(text);
//setOnclickListner on my imageButton
imageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//pass the position of my clicks to the myIconAdapterInterface
myIconAdapterInterface.setOnClickListnerMyImageButton(i);
}
});
return convertView;
}
}
4) Finally we have to change the MainActivity.java's code:
implement our class with the new interface that we have create in our IconAdapter;
modify our list data type;
pass the newest list and the interface to the IconAdapter;
implement the interface's methods.
//I implement my MainActivity with IconAdapter.MyIconAdapterInterface. I create this interface
//in the iconAdapter class
public class MainActivity extends AppCompatActivity implements IconAdapter.MyIconAdapterInterface {
//change to iconIDTextList and change List data type
List<IconData> iconIDTextList;
IconAdapter iconAdapter;
ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//istantiate my components
iconIDTextList = new ArrayList<>();
listView = findViewById(R.id.listViewIcon);
//the second "this" is refer to the IconAdapter.MyIconAdapterInterface
iconAdapter = new IconAdapter(this, iconIDTextList, this);
int myIcon = R.drawable.ic_launcher_background;
String myText = "Hello! ";
//populate the list with icon's id and text
for (int i = 0; i < 5; i++) {
iconIDTextList.add(new IconData(myIcon, myText + i));
}
//set my custom adapter to the listView
listView.setAdapter(iconAdapter);
//set clickListner to the elements of my listView
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
//i is the index of the clicked element
Toast.makeText(MainActivity.this, "Click on element n. " + i, Toast.LENGTH_SHORT).show();
}
});
}
//this is IconAdapter.MyIconAdapterInterface's method that I have to implement
#Override
public void setOnClickListnerMyImageButton(int position) {
//position = click's position
Toast.makeText(this, "Click on image n. "
+ position, Toast.LENGTH_SHORT).show();
}
}
Good Job!!
I am new to android programming and this task is really need for my school project. Please kindly help me.
I've string array List - (retrieved from csv)
list = new ArrayList<>(Arrays.asList("111,222,333,444,555,666".split(",")));
myList.setAdapter(new ArrayAdapter<String>(getActivity(),R.layout.cell,list));
The result is showing only line by line text of arrayList. I want to add button to each generated line by line to delete clicked row.
Please how can I do this. Thank you for understanding my problem.
You have to create a custom layout xml which having a single item then you will add your button to this layout along with any other items.
CustomLayout.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" >
<TextView
android:id="#+id/tvContact"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:textStyle="bold" />
<Button
android:id="#+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Call" />
</RelativeLayout>
Now after creating custom item layout you need listview which holds all items.
MainActivity.xml
.
.
<ListView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/listview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
.
.
Now in java file just set adapter with our custom layout xml
.
.
list = new ArrayList<String>(Arrays.asList("111,222,333,444,555,666".split(",")));
listview.setAdapter(new MyCustomAdapter(list, context) );
.
.
Custom adapter Class
public class MyCustomAdapter extends BaseAdapter implements ListAdapter {
private ArrayList<String> list = new ArrayList<String>();
private Context context;
public MyCustomAdapter(ArrayList<String> list, Context context) {
this.list = list;
this.context = context;
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int pos) {
return list.get(pos);
}
#Override
public long getItemId(int pos) {
return list.get(pos).getId();
//just return 0 if your list items do not have an Id variable.
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.CustomLayout, null);
}
//Handle TextView and display string from your list
TextView tvContact= (TextView)view.findViewById(R.id.tvContact);
tvContact.setText(list.get(position));
//Handle buttons and add onClickListeners
Button callbtn= (Button)view.findViewById(R.id.btn);
callbtn.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
//do something
}
});
addBtn.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
//do something
notifyDataSetChanged();
.
}
});
return view;
}
}
We have need ListviewActivity for listing your data
SchoolAdapter which is custom adapter to inflate each individual row
activity_listview which is layout for ListviewActivity
view_listview_row which is required for each individual row
Now create all file as below
For ListviewActivity,
public class ListviewActivity extends AppCompatActivity {
private ListView mListview;
private ArrayList<String> mArrData;
private SchoolAdapter mAdapter;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_listview);
mListview = (ListView) findViewById(R.id.listSchool);
// Set some data to array list
mArrData = new ArrayList<String>(Arrays.asList("111,222,333,444,555,666".split(",")));
// Initialize adapter and set adapter to list view
mAdapter = new SchoolAdapter(ListviewActivity.this, mArrData);
mListview.setAdapter(mAdapter);
mAdapter.notifyDataSetChanged();
}
For SchoolAdapter,
public class SchoolAdapter extends BaseAdapter {
private Context mContext;
private ArrayList<String> mArrSchoolData;
public SchoolAdapter(Context context, ArrayList arrSchoolData) {
super();
mContext = context;
mArrSchoolData = arrSchoolData;
}
public int getCount() {
// return the number of records
return mArrSchoolData.size();
}
// getView method is called for each item of ListView
public View getView(int position, View view, ViewGroup parent) {
// inflate the layout for each item of listView
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.view_listview_row, parent, false);
// get the reference of textView and button
TextView txtSchoolTitle = (TextView) view.findViewById(R.id.txtSchoolTitle);
Button btnAction = (Button) view.findViewById(R.id.btnAction);
// Set the title and button name
txtSchoolTitle.setText(mArrSchoolData.get(position));
btnAction.setText("Action " + position);
// Click listener of button
btnAction.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Logic goes here
}
});
return view;
}
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}}
For activity_listview,
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#D1FFFF"
android:orientation="vertical">
<ListView
android:id="#+id/listSchool"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:divider="#0000CC"
android:dividerHeight="0.1dp"></ListView>
For view_listview_row,
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="7.5dp"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:paddingTop="7.5dp">
<TextView
android:id="#+id/txtSchoolTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="2dp"
android:text="TextView"
android:textColor="#android:color/black"
android:textSize="20dp" />
<Button
android:id="#+id/btnAction"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:text="Click Me" />
At last but not least, do not forgot to add your activity in manifest.xml
Create a custom list view in another file with the only content of each item in the list.
Then create a Custom Adapter extending BaseAdapter and bind it.
Please refer to this website for example.
https://looksok.wordpress.com/tag/listview-item-with-button/
OR
http://www.androidhive.info/2012/02/android-custom-listview-with-image-and-text/
Can we use String array with custom adapter and data should be display in Listview?
I mean something like that
String [] s= {"cars","bike","train"};
Now how this string array will attach with Custom adapter and how data will show in the ListView.
I know this is easy with ArrayList.
But I want to do it with simple String Array.
Well, you can use a custom adapter for that. But you could also use the ArrayAdapter class if you just want to show text on your ListView.
But, if for whatever reason you want to create a custom adapter, try the following...
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.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"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"/>
</RelativeLayout>
Here I've created a row that displays a text.
Now, I'll create my custom adapter to handle this XML. As you can see below.
MyAdapter.java
public class MyAdapter extends BaseAdapter {
private static final String LOG_TAG = MyAdapter.class.getSimpleName();
private Context context_;
private ArrayList<String> items;
public MyAdapter(Context context, ArrayList<String> 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 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 = (TextView) convertView.findViewById(R.id.tv);
String text = items.get(position);
Log.d(LOG_TAG,"Text: " + text);
tv.setText(text);
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 item"
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 numItem = 1; // Dummy int to create my items with different numbers.
private MyAdapter myAdapter; // Your custom adapter.
private ArrayList<String> items; // This is going to be your data structure, every time 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 = (ListView) findViewById(R.id.listView);
items = new ArrayList<>();
myAdapter = new MyAdapter(this,items);
lv.setAdapter(myAdapter);
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.
}
});
}
private void addItem() {
items.add("Text " + numItem++);
mailAdapter.notifyDataSetChanged(); // Notifying the adapter that my ArrayList was modified.
}
}
This should do the trick.
From what you told me, you want to use a String array instead of a ArrayList<String>. Well, change the adapter to the following.
MyAdapter.java
public class MyAdapter extends BaseAdapter {
private static final String LOG_TAG = MyAdapter.class.getSimpleName();
private Context context_;
private String[] items;
public MyAdapter(Context context, String[] items) {
this.context_ = context;
this.items = items;
}
#Override
public int getCount() {
return items.length;
}
#Override
public Object getItem(int position) {
return items[position];
}
#Override
public long getItemId(int position) {
return position;
}
// Rest of the code... Same as before.
}
MainActivity.java
public class MainActivity extends ActionBarActivity {
private MyAdapter myAdapter; // Your custom adapter.
private String[] items;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button bt = (Button) findViewById(R.id.button);
ListView lv = (ListView) findViewById(R.id.listView);
items = {"Whatever","String","You","Like"};
myAdapter = new MyAdapter(this,items);
lv.setAdapter(myAdapter);
}
}
The problem with this approach: Your adapter will have a fixed size, which will be the size of your String array once you create it. And you won't be able to make it bigger, unless you create another adapter with a different String array.
This question discusses this matter.
I have an activity that get data (arraylist) from a previous activity and put it in a listview through a custom adapter. In this custom adapter i declare a textview (to show the data) and add a numberpicker for each row.
I want the user to be able to select a number (with numberpicker) and when he has finished, to click on a button (fini) that display data with its numberpicker value in a textview.
My activity code (choozQr3.java):
public class ChoozQr3 extends Activity {
Button fini;
ListView lv;
TextView logQr;
Context context;
ChoozQr3Adapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.choozqr_step3);
fini = (Button) findViewById(R.id.fini);
lv = (ListView) findViewById(R.id.listView1);
logQr = (TextView) findViewById(R.id.textView2);
Bundle b = getIntent().getExtras();
String[] sTemp = b.getStringArray("arrangedItems");
ArrayList<String> resultArr = new ArrayList<String>(Arrays.asList(sTemp));
adapter = new ChoozQr3Adapter(this, R.layout.choozqr_step3_textview, resultArr);
lv.setAdapter(adapter);
lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
fini.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
//ArrayList<String> finalItems = new ArrayList<String>();
for (int i = 0; i < adapter.getCount(); i++) {
Toast.makeText(getApplicationContext(),i+". " +adapter.getItem(i).toString(),Toast.LENGTH_LONG).show();
//finalItems.add(adapter.getItem(i).toString());
}
}
}
);
}
}
Here is the code of my customadapter :
public class ChoozQr3Adapter extends ArrayAdapter<String>{
private final List<String> list;
public ChoozQr3Adapter(Context context, int resource, List<String> items) {
super(context, resource, items);
list = items;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi;
vi = LayoutInflater.from(getContext());
v = vi.inflate(R.layout.choozqr_step3_textview, parent, false);
//ContentValues cv = new ContentValues();
}
TextView tvNomDuQr=(TextView)v.findViewById(R.id.NomQr);
NumberPicker npNbJours=(NumberPicker)v.findViewById(R.id.numberPickerOccurence);
tvNomDuQr.setText(list.get(position));
npNbJours.setMaxValue(365);
npNbJours.setMinValue(1);
npNbJours.setValue(1);
npNbJours.setWrapSelectorWheel(true);
return v;
}
}
And the XML related to the adapter :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/RelativeLayout1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingBottom="6dip"
android:paddingTop="4dip" >
<TextView
android:id="#+id/NomQr"
android:layout_width="400dp"
android:layout_height="80dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:gravity="center_vertical"
android:paddingLeft="6dip"
android:textAppearance="?android:attr/textAppearanceLarge" />
<NumberPicker
android:id="#+id/numberPickerOccurence"
android:layout_width="wrap_content"
android:layout_height="80dp"
android:layout_alignTop="#+id/NomQr"
android:layout_marginLeft="20dp"
android:layout_toLeftOf="#+id/textView1"
android:orientation="horizontal" />
<TextView
android:id="#+id/textView1"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:gravity="center_vertical"
android:paddingLeft="6dip"
android:text="jours"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
Until now, i managed to do it with setOnItemClickListener as described in this code (from activity choozQr3.java) :
lv.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick(AdapterView<?> arg0, View v,int position, long arg3){
// when user clicks on ListView Item , onItemClick is called
// with position and View of the item which is clicked
// we can use the position parameter to get index of clicked item
TextView tvNomDuQr=(TextView)v.findViewById(R.id.NomQr);
NumberPicker npNbJours=(NumberPicker)v.findViewById(R.id.numberPickerOccurence);
String NomDuQr=tvNomDuQr.getText().toString();
Integer NbJours=npNbJours.getValue();
// Show The result
Toast.makeText(getApplicationContext(),"répéter "+NbJours+" fois le questionnaire "+NomDuQr,Toast.LENGTH_LONG).show();
}
});
But i don't know how to modify my fini.setOnClickListener () to achieve same result...
Any help would be greatly appreciated...
Finally find the solution by myself.
public void onClick(View v) {
ArrayList<String> QrEtOccurence = new ArrayList<String>();
TextView tvNomDuQr;
NumberPicker npNbJours;
Integer j = 0;
for (int i = 0; i < lv.getCount(); i++) {
v = lv.getChildAt(i);
tvNomDuQr=(TextView)v.findViewById(R.id.NomQr);
npNbJours=(NumberPicker)v.findViewById(R.id.numberPickerOccurence);
String NomDuQr=tvNomDuQr.getText().toString();
Integer NbJours=npNbJours.getValue();
String output = "Présenter durant "+NbJours+" jours le questionnaire "+NomDuQr;
QrEtOccurence.add(output);}
String[] outputStrArr = new String[QrEtOccurence.size()];
for (int i = 0; i < QrEtOccurence.size(); i++) {
outputStrArr[i] = QrEtOccurence.get(i);}
}
My ListView in Activity:
ListView listView1 = (ListView) menu.findViewById(R.id.menuList);
String menuItems[] = new String[] { "My Wants", "Profile", "Notifications",
"Feedback", "Logout" };
listView1.setAdapter(new SideMenuAdapter(this, menuItems, listView1));
listView1.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
if (position == 1) {
Intent intent = new Intent(FeedListViewActivity.this,
UserProfileActivity.class);
startActivity(intent);
}
if (position == 0) {
showMyWants();
}
}
});
menu is :
menu = inflater.inflate(R.layout.horz_scroll_menu, null);
horz_scroll_menu.xml is:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/menu"
android:layout_width="1dp"
android:layout_height="1dp"
android:background="#FFFFFFFF"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#FF000000"
android:text="Menu"
android:textColor="#FFFFFFFF"
android:gravity="center" />
<ListView
android:id="#+id/menuList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:cacheColorHint="#FFFFFFFF"
android:scrollbars="none" >
</ListView>
</LinearLayout>
My SideMenuAdapter:
public class SideMenuAdapter extends BaseAdapter {
private static final int TYPE_MAX_COUNT = 2;
private static LayoutInflater inflater = null;
private Activity activity;
public ImageLoader imageLoader;
public static String[] values;
ListView myList;
public SideMenuAdapter(Activity a, String[] sa, ListView lv) {
values = sa;
activity = a;
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
myList = lv;
}
public int getCount() {
return values.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public static class ViewHolder {
public TextView mainText;
public TextView sideText;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = new ViewHolder();
View vi = convertView;
LayoutInflater inflater = activity.getLayoutInflater();
vi = inflater.inflate(R.layout.side_menu_list_item, null);
holder.mainText = (TextView) vi.findViewById(R.id.mainText_sideMenu);
holder.sideText = (TextView) vi.findViewById(R.id.sideText_sideMenu);
vi.setTag(holder);
holder.mainText = (TextView) vi.findViewById(R.id.mainText_sideMenu);
holder.sideText = (TextView) vi.findViewById(R.id.sideText_sideMenu);
holder.mainText.setText(values[position]);
if (position == 2) {
holder.sideText.setText("3");
holder.sideText.setBackgroundResource(R.drawable.orange);
}
return vi;
}
#Override
public int getViewTypeCount() {
return TYPE_MAX_COUNT;
}
}
My Xml for ListView items:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/sideMenuListItem"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_horizontal"
android:orientation="horizontal"
android:padding="3dp" >
<TextView
android:id="#+id/sideText_sideMenu"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentRight="true"
android:clickable="true"
android:gravity="center"
android:textSize="20dp"
android:padding="5dp" />
<TextView
android:id="#+id/mainText_sideMenu"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="#id/sideText_sideMenu"
android:clickable="true"
android:gravity="left|center_vertical"
android:textSize="20dp"
android:padding="5dp" />
</RelativeLayout>
when running this application on Emulator, if i click with mouse nothing happens. But when i select any item on the list using navigation buttons on the KeyBoard and click Enter, it works fine.
when running the app on a device. If i go on click any item of the list, like some 10-20 times it works sometimes.
Edit:
Actually everything worked fine when i was using predefined ArrayAdapter<String> and android.R.simple_list_item. But i want a custom adapter
why is it so?
Its because in my ListView item layout i added
android:clickable="true"
for both the TextViews. So when i click on the ListView item it indeed is a click on these TextView whose onClick is not implemented. Removing the clickable attribute from the TextViews solved my problem.
Thanks everyone
Try making the RelativeLayout clickable and focusable.
Layout File
<ListView android:id="#id/android:list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#000fff"
android:layout_weight="2"
android:drawSelectorOnTop="false">
</ListView>
Main Activity
public class MyListView extends ListActivity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, PENS));
getListView().setTextFilterEnabled(true);
}
static final String[] PENS = new String[]{
"MONT Blanc",
"Gucci",
"Parker",
"Sailor",
"Porsche Design",
"Rotring",
"Sheaffer",
"Waterman"
};
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Object o = this.getListAdapter().getItem(position);
String pen = o.toString();
Toast.makeText(this, "You have chosen the pen: " + " " + pen, Toast.LENGTH_LONG).show();
}
}
try this one
http://www.mkyong.com/android/android-listview-example/
res/layout/list_fruit.xml
<?xml version="1.0" encoding="utf-8"?>
<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="20sp" >
</TextView>
ListView
public class ListFruitActivity extends ListActivity {
static final String[] FRUITS = new String[] { "Apple", "Avocado", "Banana",
"Blueberry", "Coconut", "Durian", "Guava", "Kiwifruit",
"Jackfruit", "Mango", "Olive", "Pear", "Sugar-apple" };
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// no more this
// setContentView(R.layout.list_fruit);
setListAdapter(new ArrayAdapter<String>(this, R.layout.list_fruit,FRUITS));
ListView listView = getListView();
listView.setTextFilterEnabled(true);
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// When clicked, show a toast with the TextView text
Toast.makeText(getApplicationContext(),
((TextView) view).getText(), Toast.LENGTH_SHORT).show();
}
});
}
}