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.
Related
I'm using RecyclerView with select all option.this option select screen visible items only. Not all select. But I scroll top to bottom after selected. what is the problem?
Adapter class:
public class FilterBrandAdapter extends RecyclerView.Adapter<FilterBrandAdapter.MyViewHolder> {
private ArrayList<FilterBrandDataModel> mBrandModelArraylist;
private Context mContext;
private TinyDB mPrefDb;
private boolean isSelectedAll;
public static final String PREF_SELECTED_ALL = "selectedAll";
private CartTotalListener mCartListener;
public void selectAll() {
Log.e("onClickSelectAll", "yes");
isSelectedAll = true;
notifyDataSetChanged();
}
public void deselectAll() {
Log.e("onClickSelectAll", "no");
isSelectedAll = false;
notifyDataSetChanged();
}
class MyViewHolder extends RecyclerView.ViewHolder {
CheckBox cbItemTitle;
MyViewHolder(View itemView) {
super(itemView);
cbItemTitle = (CheckBox) itemView.findViewById(R.id.checkBox_filter_brand_title);
itemView.setClickable(true);
}
}
public FilterBrandAdapter(BrandFilterActivity activity, ArrayList<FilterBrandDataModel> mArrayList) {
this.mContext = activity;
this.mBrandModelArraylist = mArrayList;
LayoutInflater inflater = activity.getLayoutInflater();
try {
this.mCartListener = ((CartTotalListener) mContext);
} catch (ClassCastException e) {
throw new ClassCastException("Activity must implement AdapterCallback.");
}
}
#Override
public FilterBrandAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_recycler_brand_items, parent, false);
mPrefDb = new TinyDB(mContext);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
final FilterBrandDataModel brandsData = mBrandModelArraylist.get(position);
holder.cbItemTitle.setText(mBrandModelArraylist.get(position).getCategoryName());
//set adapter classcheckbox change listener for if clicked or not
holder.cbItemTitle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (holder.cbItemTitle.isChecked()) {
//if check box checked selected checkbox saved in tinyDB
int getPosition = (int) buttonView.getTag();
mBrandModelArraylist.get(getPosition).setSelected(buttonView.isChecked());
mPrefDb.putBoolean(brandsData.getCategoryName(), true);
holder.cbItemTitle.setChecked(true);
Log.e("checked item-->", brandsData.getCategoryName());
mCartListener.onMethodCallback();
} else {
//else check box un-checked selected checkbox save checkbox is un-checked in tinyDB
int getPosition = (int) buttonView.getTag();
mBrandModelArraylist.get(getPosition).setSelected(buttonView.isChecked());
mPrefDb.putBoolean(brandsData.getCategoryName(), false);
holder.cbItemTitle.setChecked(false);
Log.e("un-checked item-->", brandsData.getCategoryName());
mCartListener.onMethodCallback();
}
}
});
//select & deselect all checkbox in recyclerview
if (!isSelectedAll) {
holder.cbItemTitle.setTag(position);
holder.cbItemTitle.setChecked(mBrandModelArraylist.get(position).isSelected());
holder.cbItemTitle.setChecked(false);
} else {
holder.cbItemTitle.setTag(position);
holder.cbItemTitle.setChecked(mBrandModelArraylist.get(position).isSelected());
holder.cbItemTitle.setChecked(true);
}
//save selected (or) deselect checkbox with position in tinyDB
holder.cbItemTitle.setTag(position);
holder.cbItemTitle.setChecked(mBrandModelArraylist.get(position).isSelected());
boolean checked = mPrefDb.getBoolean(brandsData.getCategoryName(), true);
holder.cbItemTitle.setChecked(checked);
}
#Override
public int getItemCount() {
return mBrandModelArraylist.size();
}
}
I use interface(mCartListener.onMethodCallback()) for notify selected items & display items counts in text view.
my interface:
#Override
public void onMethodCallback() {
ArrayList<String> array = new ArrayList<>();
//checking which items are selected in adapter class & save into array list
for (FilterBrandDataModel brandDataModel : mArrayList) {
if (brandDataModel.isSelected()) {
array.add(brandDataModel.getCategoryName());
}
}
int size = array.size();
if (size == mArrayList.size()) {
mPrefDb.putString(PREF_SELECTED_BRANDS_TOT, "true");
String text = String.valueOf(size) + " " + getResources().getString(R.string.msg_selected);
mBrandResults.setText(text);
} else {
mPrefDb.putString(PREF_SELECTED_BRANDS_TOT, "false");
String text = String.valueOf(size) + " " + getResources().getString(R.string.msg_selected);
mBrandResults.setText(text);
}
}
RecyclerView loads the data while scrolling, but I need all data in it without scrolling. So, I changed the RecyclerView in ScrollView like that:
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.85"
android:overScrollMode="never"
android:scrollbars="none">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:overScrollMode="never"
/>
</ScrollView>
then, in the Activity,
RecyclerView.setNestedScrollEnabled(false);
I use the ScrollView to scroll items. That's it.
The problem is that you only switch a flag in selectAll() (isSelectedAll = true;). In your adapter there will be for example 3 visible items (i don't know how big they are at your screen). One item is represented by one viewholder. After you switch the flag and call notifyDataSetChanged() the function onBindViewHolder() will be called for every visible item -> in my example 3 times. In this function you decide with if (!isSelectedAll) { if the checkbox should be selected. So it will never be called for all items.
Solution:
Change
public void selectAll() {
Log.e("onClickSelectAll", "yes");
isSelectedAll = true;
notifyDataSetChanged();
}
To
public void selectAll() {
Log.e("onClickSelectAll", "yes");
for(FilterBrandDataModel brandsData : mBrandModelArraylist) {
mPrefDb.putBoolean(brandsData.getCategoryName(), true);
}
notifyDataSetChanged();
}
And the same for deselectAll().
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!!
I'm trying to change the color of each row, I have 2 arrays. One has names of color, the other has color codes.
I have a ListView with Color names, the names are stored in an array of String.
String[] colourNames;
String[] colourCodes;
protected void onCreate(Bundle savedInstanceState) {
colourNames = getResources().getStringArray(R.array.listArray);
colourCodes = getResources().getStringArray(R.array.listValues);
ListView lv = (ListView) findViewById(R.id.listView);
ArrayAdapter aa = new ArrayAdapter(this, R.layout.activity_listview, colourNames);
lv.setAdapter(aa);
for(int i=0; i<colourCodes.length; i++)
lv.getChildAt(i).setBackgroundColor(Color.parseColor(colourCodes[i]));
}
In arrays.xml:
<string-array name="listArray">
<item>aliceblue</item>
<item>antiquewhite</item>
<item>aquamarine</item>
<item>azure</item>
</string-array>
<string-array name="listValues">
<item>00f0f8ff</item>
<item>00faebd7</item>
<item>007fffd4</item>
<item>00f0ffff</item>
</string-array>
The app crashes at lv.getChildAt(i).setBackgroundColor(Color.parseColor(colourCodes[i]));
You must write your own custom ArrayAdapter.
First write a color class:
color.java:
public class color {
private String name;
private String color;
public color(String name, String color) {
this.name = name;
this.color = color;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
Then List item layout:
list_item_layout.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/name"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Finally write custom adapter:
ColorListAdapter.java:
public class ColorListAdapter extends BaseAdapter {
private LayoutInflater mInflater;
private List<color> mColorList;
public ColorListAdapter(Activity activity, List<color> mColorList) {
mInflater = (LayoutInflater) activity.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
this.mColorList = mColorList;
}
#Override
public int getCount() {
return mColorList.size();
}
#Override
public Object getItem(int position) {
return mColorList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView;
// Get item_layout:
rowView = mInflater.inflate(R.layout.list_item_layout, null);
// Get TextView from item_layout:
TextView textView =
(TextView) rowView.findViewById(R.id.name);
// Get color and text from current position set TextView
color myColor = mColorList.get(position);
textView.setText(myColor.getName());
textView.setBackgroundColor(Color.parseColor(myColor.getColor()));
return rowView;
}
}
And these are MainActivity.java and activity_main.xml
MainActivity.java:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
List<color> colorList = new ArrayList<>();
// Add color objects:
colorList.add(new color("RED", "#FF0000"));
colorList.add(new color("GREEN", "#00FF00"));
colorList.add(new color("BLUE", "#0000FF"));
colorList.add(new color("MY BEST", "#013583"));
// Add list to your custom adapter
ListView myListView = (ListView) findViewById(R.id.liste);
ColorListAdapter mAdapter = new ColorListAdapter(this, colorList);
// Set Adapter
myListView.setAdapter(mAdapter);
}
activity_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="#+id/liste"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center" />
</RelativeLayout>
Try this code
String[] colourNames;
String[] colourCodes;
protected void onCreate(Bundle savedInstanceState) {
colourNames = getResources().getStringArray(R.array.listArray);
colourCodes = getResources().getStringArray(R.array.listValues);
ListView lv = (ListView) findViewById(R.id.listView);
ArrayAdapter aa = new ArrayAdapter(this, R.layout.activity_listview, colourNames);
lv.setAdapter(aa);
for(int i=0; i<colourCodes.length; i++){
View wantedView = lv.getChildAt(i);
view.setBackgroundColor(Color.BLUE);
}
}
The problem is at this point ListView does not have any children. If you want to alter how children are displayed, you need create your own Adapter implementation and override getView(). You can simply subclass ArrayAdapter in this case and pass it your array of colors (or have it load the colors in the adapter, as I have done), then choose a color based on position.
Also, you might as well make your colors an integer array.
<integer-array name="listValues">
<item>0xfff0f8ff</item>
<item>0xfffaebd7</item>
<item>0xff7fffd4</item>
<item>0xfff0ffff</item>
</integer-array>
public class ColorsAdapter extends ArrayAdapter<String> {
private int[] mColors;
public ColorsAdapter(Context context) {
super(context, R.layout.activity_listview,
context.getResources().getStringArray(R.array.listArray));
mColors = context.getResources().getIntegerArray(R.array.listValues);
{
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
int color = mColors[position % mColors.length]; // might as well be safe
view.setBackgroundColor(color);
return view;
}
}
I also highly recommend watching this video on how ListView works: The World of ListView. Also, nowadays people are moving toward RecyclerView instead; you don't have to do that necessarily, but either way this video should help you understand how these components behave.
I get rows from a db as an ArrayList. I want to use data that is in two of the columns to populate a list view.
What I have done so far only shows the ?row reference? (com.app.Poster#2349049)
ListView listView = (ListView) findViewById(R.id.poster_list_view);
MySQLiteHelper db = new MySQLiteHelper(this);
List<Poster> posters = db.getAllPosters();
ArrayAdapter<Poster> listAdapter = new ArrayAdapter<Poster>(this, android.R.layout.simple_list_item_1, posters);
listView.setAdapter(listAdapter);
I thought maybe I am suppose to loop the ArrayList and add each row to the adapter
for (Poster p : posters){
listAdapter.add(p.getPosterTitle());
}
Apparently the adapter only wants an object I think. Should I be customizing an adapter for this? I thought it would be a lot easier.
This is my Poster Class
public class Poster {
private int posterId;
private int categoryId;
private int eventId;
private String presenterFname;
private String presenterLname;
private String posterTitle;
private String posterSynopsis;
private String posterFilename;
private String posterRemoteLocation;
public Poster(int pid, int cid, int eid, String prf, String prl, String pt, String ps, String pfn, String fl){
posterId = pid;
categoryId = cid;
eventId = eid;
presenterFname = prf;
presenterLname = prl;
posterTitle = pt;
posterSynopsis = ps;
posterFilename = pfn;
posterRemoteLocation = fl;
}
public int getPosterID(){
return this.posterId;
}
public int getCatID(){
return this.categoryId;
}
public int getEventId(){
return this.eventId;
}
public String getPresenterFname(){
return this.presenterFname;
}
public String getPresenterLname(){
return this.presenterLname;
}
public String getPosterTitle(){
return this.posterTitle;
}
public String getPosterSynopsis(){
return this.posterSynopsis;
}
public String getPosterFilename(){
return this.posterFilename;
}
public String getPosterRemote(){
return this.posterRemoteLocation;
}
}
You can find the class for a custom adapter to vaguely fit your needs below. This will work in pretty much the same way that you are trying to use the general one in your code sample.
This method will give you more flexibility in the way your information is displayed.
You can set the custom layout in the getView method. As well as set the values in the view from the item number passed in.
public class PosterListAdapter extends BaseAdapter {
private final ArrayList<Poster> listItems;
private final LayoutInflater inflater;
public PosterListAdapter(ArrayList<Poster> listItems, LayoutInflater inflater) {
this.listItems = listItems;
this.inflater = inflater;
}
#Override
public int getCount() {
return this.listItems.size();
}
#Override
public Film getItem(int i) {
return this.listItems.get(i);
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
if (view == null) {
view = inflater.inflate(R.layout.poster_layout, viewGroup, false);
}
Poster item = this.listItems.get(i);
TextView posterTitle = ((TextView) view.findViewById(R.id.poster_layout_title));
posterTitle.setText(item.getTitle());
ImageView posterImage = ((ImageView) view.findViewById(R.id.poster_layout_image));
posterImage.setImageResource(R.drawable.apple);
return view;
}
}
Below you will find a simple layout that can be used with the above array adapter for a list view item.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="100dp"
android:orientation="vertical">
<ImageView
android:id="#+id/poster_layout_image"
android:layout_width="50dp"
android:layout_height="75dp"
android:layout_centerVertical="true"
android:src="#drawable/ic_launcher" />
<TextView
android:id="#+id/poster_layout_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/poster_layout_image"
android:textColor="#color/text"
android:textSize="20sp" />
</RelativeLayout>
Is there a good tutorial or link that shows how to add different items to a listview?
For example, one with two Text lines and a Check box, another that you just press and and something would pop up. All I have now is every list item is the same two line text view and checkbox...
Or, if there is a way to add 1 row at a time with a different layout through R.layout.xxx?
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mRoot = inflater.inflate(R.layout.frag_settings, container, false);
mItems = getResources().getStringArray(R.array.setting_items);
mItemDescription = getResources().getStringArray(R.array.setting_item_descriptions);
mItemListView = (ListView) mRoot.findViewById(R.id.lvMainListView);
ArrayAdapter<String> lvRowTitle = new ArrayAdapter<String>(getActivity(),
R.layout.setting_twolinetext_checkbox, R.id.tvRowTitle,
mItems);
mItemListView.setAdapter(lvRowTitle);
ArrayAdapter<String> lvRowDesc = new ArrayAdapter<String>(getActivity(),
R.layout.setting_twolinetext_checkbox, R.id.tvRowDesc,
mItemDescription);
mItemListView.setAdapter(lvRowDesc);
return mRoot;
In my example, the list activity that will display our custom list view is called OptionsActivity, because in my project this activity is going to display the different options my user can set to control my app. There are two list item types, one list item type just has a TextView and the second list item type just has a Button. You can put any widgets you like inside each list item type, but I kept this example simple.
The getItemView method checks to see which list items should be type 1 or type 2. According to my static ints I defined up top, the first 5 list items will be list item type 1, and the last 5 list items will be list item type 2. So if you compile and run this, you will have a ListView that has five items that just contain a button, and then five items that just contain a TextView.
Below is the activity code, the activity xml file, and an xml file for each list item type.
OptionsActivity.java:
public class OptionsActivity extends ListActivity {
private static final int LIST_ITEM_TYPE_1 = 0;
private static final int LIST_ITEM_TYPE_2 = 1;
private static final int LIST_ITEM_TYPE_COUNT = 2;
private static final int LIST_ITEM_COUNT = 10;
// The first five list items will be list item type 1
// and the last five will be list item type 2
private static final int LIST_ITEM_TYPE_1_COUNT = 5;
private MyCustomAdapter mAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mAdapter = new MyCustomAdapter();
for (int i = 0; i < LIST_ITEM_COUNT; i++) {
if (i < LIST_ITEM_TYPE_1_COUNT)
mAdapter.addItem("item type 1");
else
mAdapter.addItem("item type 2");
}
setListAdapter(mAdapter);
}
private class MyCustomAdapter extends BaseAdapter {
private ArrayList<String> mData = new ArrayList<String>();
private LayoutInflater mInflater;
public MyCustomAdapter() {
mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public void addItem(final String item) {
mData.add(item);
notifyDataSetChanged();
}
#Override
public int getItemViewType(int position) {
if(position < LIST_ITEM_TYPE_1_COUNT)
return LIST_ITEM_TYPE_1;
else
return LIST_ITEM_TYPE_2;
}
#Override
public int getViewTypeCount() {
return LIST_ITEM_TYPE_COUNT;
}
#Override
public int getCount() {
return mData.size();
}
#Override
public String getItem(int position) {
return mData.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
int type = getItemViewType(position);
if (convertView == null) {
holder = new ViewHolder();
switch(type) {
case LIST_ITEM_TYPE_1:
convertView = mInflater.inflate(R.layout.list_item_type1, null);
holder.textView = (TextView)convertView.findViewById(R.id.list_item_type1_text_view);
break;
case LIST_ITEM_TYPE_2:
convertView = mInflater.inflate(R.layout.list_item_type2, null);
holder.textView = (TextView)convertView.findViewById(R.id.list_item_type2_button);
break;
}
convertView.setTag(holder);
} else {
holder = (ViewHolder)convertView.getTag();
}
holder.textView.setText(mData.get(position));
return convertView;
}
}
public static class ViewHolder {
public TextView textView;
}
}
activity_options.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<ListView
android:id="#+id/optionsList"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
list_item_type_1.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/list_item_type1_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/list_item_type1_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text goes here" />
</LinearLayout>
list_item_type2.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/list_item_type2_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="#+id/list_item_type2_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button text goes here" />
</LinearLayout>
You have two possibilities to do that:
Create a Type and check for your type and return the view related to this type.
BaseAdapter has two methods to check different items in it, getItemViewType(int position) and getViewTypeCount(). Do your stuff there.
Check this tutorial:
ListView with multiple rows
You should create your own class extending BaseAdapter. I recommend watching The World of ListView, it will help you understand everything you need to know about working with ListView.
In addition to #LouMorda answer, I'd use some class, with fields that contains info about item and list item type:
public class Item {
private int itemViewType;
private Object tag;
private String title;
public Item(int itemViewType){
this.itemViewType = itemViewType;
}
public int getItemViewType() {
return itemViewType;
}
public void setItemViewType(int itemViewType) {
this.itemViewType = itemViewType;
}
...
}
So using this object gives more flexibility when adding items to the list in different sequences:
public class OptionsActivity extends ListActivity {
private static final int LIST_ITEM_TYPE_1 = 0;
private static final int LIST_ITEM_TYPE_2 = 1;
private ArrayList<String> mItemsSource = new ArrayList<>();
...
#Override
public int getItemViewType(int position) {
return mItemsSource.get(position).getItemViewType();
}
...
}