Basically all I'm trying to do is have a button appear in a row, when the row is selected. I have tried many methods, and they all seem to work including the one below...I get the ImageView but calling setVisibility() on it does nothing:
ListFragment
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
setSellButton();
}
public View getViewForPosition(int position){
int relativePos = position - listview.getFirstVisiblePosition();
if( relativePos < 0 || relativePos > listview.getChildCount()){
return null;
}
return listview.getChildAt(relativePos);
}
public void setSellButton() {
View x = getViewForPosition(Constants.lastSelection);
ImageView y = (ImageView)x.findViewById(R.id.ivSell);
y.setVisibility(View.VISIBLE);
}
No errors, and debug shows that everything is right in setSellButton() but setVisibility() never works. Is this something I can only do in the adapter? Thanks!
Edit: Row Layout XML as requested
<?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="60dp"
android:orientation="horizontal"
android:gravity="center_vertical"
android:background="#drawable/thelist"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/ivStar"
android:src="#drawable/liststar"
android:layout_weight="1" />
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_vertical"
android:layout_weight="10">
<TextView
android:id="#+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:textStyle="bold">
</TextView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tvValue"
android:textSize="13sp" />
</LinearLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/coin"
android:id="#+id/ivSell"
android:visibility="invisible" />
</LinearLayout>
Edit: Adapter
public class InventoryAdapter extends ArrayAdapter<Integer> {
private final Context context;
private final ArrayList<String> names;
private final ArrayList<Integer> stock;
LayoutInflater inflater;
View rowView;
String stockText;
TextView textView;
TextView textView2;
ImageView iv;
public InventoryAdapter(Context context, ArrayList<String> names, ArrayList<Integer> stock) {
super(context, R.layout.inv_rowlayout, stock);
this.context = context;
this.names = names;
this.stock = stock;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflater.inflate(R.layout.inv_rowlayout, parent, false);
String stockNumber = stock.get(position).toString();
final String name = names.get(position);
textView = (TextView) rowView.findViewById(R.id.label);
textView.setText(names.get(position));
textView2 = (TextView) rowView.findViewById(R.id.tvValue);
textView2.setText(stockNumber);
iv = (ImageView)rowView.findViewById(R.id.ivSell);
return rowView;
}
}
Well. First of all allow me to adapt your row xml. It's better to use RelativeLayout instead of LinearLayout. It's more flexible.
row_layout.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:background="#drawable/thelist"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:minHeight="#dimen/listView_minHeight">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/ivStar"
android:contentDescription="#string/list_item_image_desc"
android:layout_gravity="center_vertical"
android:layout_centerVertical="true"
android:src="#drawable/liststar" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/ivStar"
android:layout_toEndOf="#+id/ivStar"
android:layout_alignParentTop="true"
android:id="#+id/label"
android:text="New Text"
android:textSize="15sp"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Text"
android:textSize="13sp"
android:id="#+id/tvValue"
android:layout_below="#+id/label"
android:layout_toRightOf="#+id/ivStar"
android:layout_toEndOf="#+id/ivStar"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/ivSell"
android:src="#drawable/coin"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:visibility="invisible" />
</RelativeLayout>
You're probably subclassing BaseAdapter. What you'll have to do is to create a method there to change the visibility of your ImageView. Then when you have your item clicked, you can get the adapter and call that method.
CustomAdapter.java
public class CustomAdapter extends BaseAdapter {
private Context context_;
private ArrayList<YourDataHolder> items;
private YourDataHolder lastHolder = null;
private final String LOG_TAG = CustomAdapter.class.getSimpleName();
public CustomAdapter(Context context, ArrayList<YourDataHolder> items) {
this.context_ = context;
this.items = items;
}
#Override
public int getCount() {
return items.size();
}
#Override
public Object getItem(int i) {
return items.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int position, View convertView, ViewGroup viewGroup) {
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater)
context_.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.row_layout, null);
}
final TextView tv_label = (TextView) convertView.findViewById(R.id.label);
final TextView tv_value = (TextView) convertView.findViewById(R.id.tvValue);
final ImageView iv_star = (ImageView) convertView.findViewById(R.id.ivSell);
YourDataHolder holder = items.get(position);
tv_label.setText(holder.getLabel());
tv_value.setText(holder.getValue());
if (holder.isImageVisible() && iv_star.getVisibility() == ImageView.INVISIBLE) {
iv_star.setVisibility(ImageView.VISIBLE);
}
else if (iv_star.getVisibility() == ImageView.VISIBLE) {
iv_star.setVisibility(ImageView.INVISIBLE);
}
return convertView;
}
public void onItemSelect(int position) {
if (position < items.size()) {
YourDataHolder holder = items.get(position);
holder.setVisibility(true);
if (lastHolder != null) {
lastHolder.setVisibility(false);
}
lastHolder = holder;
}
}
}
Assuming you're using a data holder like this one:
YourDataHolder.java
public class YourDataHolder {
private String label;
private String value;
private boolean isVisible;
public YourDataHolder(String label, String value) {
this.label = label;
this.value = value;
isVisible = false;
}
public String getLabel() {
return label;
}
public String getValue() {
return value;
}
public boolean getVisibility() {
return isVisible;
}
public void setVisibility(boolean isVisible) {
this.isVisible = isVisible;
}
}
And then, on your onItemClick(), do the magic.
YourFragment.java
private CustomAdapter adapter;
// Rest of the Fragment. Where you create the adapter, and assign it to the ListView.
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
adapter.onItemSelect(position);
adapter.notifyDataSetChanged();
}
My guess is, that after the click on the item you need to call the notifyDataSetChanged method on the adapter. And then render the button on the selected list view item.
It is something that I would do in the adapter, having direct access to the imageview would make the process easier. I previously attempted to do it from the listview level and was unable to do to the conditions I had setup.
Related
I am trying to implement a GridView in Android to display a list of Products as mentioned in below image:
With Custom Button and Grid List I am implemented this.
I want to know, how can I make this Product Button Red when I select it. Or in other words, I want to get the selected cell item object and change the background color to red, TextViews text color to white. Plus, at the same time, I want to make all remaining cell items to default white background and text color to purple.
I am new to android, any help would be great support. Thanks in advance. Here is my code:
GridView in Fragment
<GridView
android:id="#+id/grid_Products"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:horizontalSpacing="10dp"
android:gravity="center"
android:numColumns="3"
android:stretchMode="columnWidth"
android:verticalSpacing="10dp />
In ProductFragment class in onCreateView() method, I am binding the productModels to gridView
List<ProductModel> productModels;
GridView gdGridView=(GridView)(view.findViewById(R.id.grid_Products));
adapter = new ProductButtonAdaptor(view.getContext(), productModels);
gdGridView.setAdapter(adapter);
product_button.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/btn_product_red"
android:id="#+id/pnl_ProudctButton"
android:orientation="vertical">
<LinearLayout
android:paddingTop="10dp"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="5"
android:gravity="center"
android:layout_gravity="center"
android:orientation="horizontal">
<TextView
android:id="#+id/lbl_ProductName"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="bottom"
android:text="5"
android:layout_marginRight="2dp"
android:textColor="#color/purple"
android:textAlignment="center"
android:textSize="30dp"
android:textStyle="bold" />
<TextView
android:id="#+id/lbl_ProductCurrency"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="2dp"
android:gravity="bottom"
android:text="QAR"
android:textAlignment="center"
android:textColor="#color/purple"
android:textSize="20dp"
android:textStyle="bold" />
</LinearLayout>
<View
android:id="#+id/lbl_ProductSeparator"
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_alignParentBottom="true"
android:layout_margin="4dp"
android:background="#color/purple" />
<TextView
android:id="#+id/lbl_ProductCategory"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="4"
android:gravity="top"
android:text="International"
android:textAlignment="center"
android:textColor="#color/purple"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:textSize="16dp" />
</LinearLayout>
ProductButtonAdpater class:
public class ProductButtonAdaptor extends ArrayAdapter<ProductModel> implements AdapterView.OnItemClickListener
{
private Context context;
private final List<ProductModel> productModels;
private int selected = -1;
public ProductButtonAdaptor(Context context, List<ProductModel> productValues)
{
super(context, R.layout.button_product, productValues);
this.context = context;
this.productModels = productValues;
}
public View getView(int position, View convertView, ViewGroup parent)
{
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View gridView;
if (convertView == null)
{
gridView = new View(context);
// get layout from button_product.xml
gridView = inflater.inflate(R.layout.button_product, null);
// set value into textview
TextView lbl_ProductName = (TextView)gridView.findViewById(R.id.lbl_ProductName);
TextView lbl_ProductCurrency = (TextView)gridView.findViewById(R.id.lbl_ProductCurrency);
TextView lbl_ProductCategory = (TextView)gridView.findViewById(R.id.lbl_ProductCategory);
lbl_ProductName.setText(productModels.get(position).getCode());
lbl_ProductCurrency.setText(productModels.get(position).getCurrency());
lbl_ProductCategory.setText(productModels.get(position).getCategoryName());
}
else
{
gridView = (View)convertView;
}
if (selected == position)
{
TextView lbl_ProductName = (TextView)gridView.findViewById(R.id.lbl_ProductName);
TextView lbl_ProductCurrency = (TextView)gridView.findViewById(R.id.lbl_ProductCurrency);
TextView lbl_ProductCategory = (TextView)gridView.findViewById(R.id.lbl_ProductCategory);
View lbl_ProductSeperator = (View)gridView.findViewById(R.id.lbl_ProductSeparator);
LinearLayout pnl_ProductButton = (LinearLayout)gridView.findViewById(R.id.pnl_ProudctButton);
lbl_ProductName.setTextColor(ContextCompat.getColor(context, R.color.vodafone_white));
lbl_ProductCurrency.setTextColor(ContextCompat.getColor(context, R.color.vodafone_white));
lbl_ProductCategory.setTextColor(ContextCompat.getColor(context, R.color.vodafone_white));
lbl_ProductSeperator.setBackgroundColor(ContextCompat.getColor(context, R.color.vodafone_white));
pnl_ProductButton.setBackground(ResourcesCompat.getDrawable(context.getResources(), R.drawable.btn_product_red, null));
}
else
{
//setup the other cells
TextView lbl_ProductName = (TextView)gridView.findViewById(R.id.lbl_ProductName);
TextView lbl_ProductCurrency = (TextView)gridView.findViewById(R.id.lbl_ProductCurrency);
TextView lbl_ProductCategory = (TextView)gridView.findViewById(R.id.lbl_ProductCategory);
View lbl_ProductSeperator = (View)gridView.findViewById(R.id.lbl_ProductSeparator);
LinearLayout pnl_ProductButton = (LinearLayout)gridView.findViewById(R.id.pnl_ProudctButton);
lbl_ProductName.setTextColor(ContextCompat.getColor(context, R.color.vodafone_purple));
lbl_ProductCurrency.setTextColor(ContextCompat.getColor(context, R.color.vodafone_purple));
lbl_ProductCategory.setTextColor(ContextCompat.getColor(context, R.color.vodafone_purple));
lbl_ProductSeperator.setBackgroundColor(ContextCompat.getColor(context, R.color.vodafone_purple));
pnl_ProductButton.setBackground(ResourcesCompat.getDrawable(context.getResources(), R.drawable.btn_product_white, null));
}
return gridView;
}
#Override
public int getCount()
{
return productModels.size();
}
#Override
public ProductModel getItem(int position)
{
return productModels.get(position);
}
#Override
public long getItemId(int position)
{
return 0;
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
selected = position;
this.notifyDataSetChanged();
//adapter.notifyDataChanged();
//parent.invalidate();
//view.invalidate();
}
}
this is the updated code
I think you want to do it programatically (not styles).
So,
You have to declare a int selected; variable which stores index of a selected cell (or -1 if none is selected). Then, you have to implement onClickListener on each cell and change selected value when any element is tapped and redraw all data grid cells using notify... method.
After that, do not forget to change the setup block of colors and other parameters of each sell in the correspond method of the adapter.
inside onCreate() method:
gridview.setOnItemClickListener(adapter);
your class:
public class ProductButtonAdaptor extends BaseAdapter implemets onItemClickListener {
private Context context;
private final ProductModel[] productModels;
private int selected = -1;
public ProductButtonAdaptor(Context context, ProductModel[] productValues) {
this.context = context;
this.productModels = productValues;
}
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View gridView;
if (convertView == null) {
gridView = new View(context);
// get layout from button_product.xml
gridView = inflater.inflate(R.layout.button_product, null);
// set value into textview
TextView lbl_ProductName = (TextView) gridView.findViewById(R.id.lbl_ProductName);
TextView lbl_ProductCurrency = (TextView) gridView.findViewById(R.id.lbl_ProductCurrency);
TextView lbl_ProductCategory = (TextView) gridView.findViewById(R.id.lbl_ProductCategory);
lbl_ProductName.setText(productModels[position].Name);
lbl_ProductCurrency.setText(productModels[position].Currency);
lbl_ProductCategory.setText(productModels[position].CategoryName);
} else {
gridView = (View) convertView;
}
if (selected == position) {
//setup selected cell
//for example
gridView.setBackgroundColor(Color.red);
} else {
//setup the other cells
gridView.setBackgroundColor(Color.white);
}
return gridView;
}
#Override
public int getCount() {
return productModels.length;
}
#Override
public Object getItem(int position) {
return productModels[position];
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
selected = position;
adapter.notifyDataChanged();
//you can pass the grid as a paramater of constructor if you need it
grid.invalidateViews();
}
I have a working navigation drawer that uses ArrayAdapter as shown in the documentation. I want to set ImageView icons for each of the navigation drawer items, so I need to create a custom adapter to use, but I am unsure of how to do that. What I have below runs without crashing the app, but the navigation drawer opens up empty, with nothing in it. Can you please help me out? Thanks in advance!
What I've done for a custom adapter so far:
public class CustomAdapter extends ArrayAdapter
{
private final Context context;
public CustomAdapter(Context context)
{
super(context, R.layout.drawer_list_item);
this.context = context;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(R.layout.drawer_list_item, parent, false);
TextView textViewHome = (TextView) v.findViewById(R.id.drawerHomeTextView);
ImageView imageViewHome = (ImageView) v.findViewById(R.id.drawerHomeImage);
TextView textViewList = (TextView) v.findViewById(R.id.drawerListTextView);
ImageView imageViewList = (ImageView) v.findViewById(R.id.drawerListImage);
return v;
}
}
Setting up the drawer in MainActivity:
mDrawerList = (ListView) findViewById(R.id.leftDrawer);
mDrawerList.setAdapter(new CustomAdapter(this));
The ListView used:
<ListView android:id="#+id/leftDrawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="left"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:background="#111"/>
drawer_list_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="match_parent">
<RelativeLayout
android:id="#+id/drawerRelativeLayoutHome"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/drawerHomeImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:paddingStart="4dp"
android:paddingEnd="4dp"
android:paddingLeft="4dp"
android:src="#drawable/ic_menu_home"/>
<TextView
android:id="#+id/drawerHomeTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/drawerHomeImage"
android:layout_toEndOf="#+id/drawerHomeImage"
android:background="#drawable/background_activated"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:paddingTop="12dp"
android:paddingBottom="12dp"
android:text="Home"
android:textSize="20sp"/>
</RelativeLayout>
<RelativeLayout
android:id="#+id/drawerRelativeLayoutList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/drawerRelativeLayoutHome">
<!-- same as above, but ic_menu_archive as drawable, and "List" as text -->
</RelativeLayout>
</RelativeLayout>
For your custom adapter:
public class NavDrawerAdapter extends ArrayAdapter<NavDrawerItem>
{
private final Context context;
private final int layoutResourceId;
private NavDrawerItem data[] = null;
public NavDrawerAdapter(Context context, int layoutResourceId, NavDrawerItem [] data)
{
super(context, layoutResourceId, data);
this.context = context;
this.layoutResourceId = layoutResourceId;
this.data = data;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
View v = inflater.inflate(layoutResourceId, parent, false);
ImageView imageView = (ImageView) v.findViewById(R.id.navDrawerImageView);
TextView textView = (TextView) v.findViewById(R.id.navDrawerTextView);
NavDrawerItem choice = data[position];
imageView.setImageResource(choice.icon);
textView.setText(choice.name);
return v;
}
}
For NavDrawerItem:
public class NavDrawerItem
{
public int icon;
public String name;
public NavDrawerItem(int icon, String name)
{
this.icon = icon;
this.name = name;
}
}
For drawer_list_item.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:background="?android:attr/activatedBackgroundIndicator"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
android:padding ="10dp">
<ImageView
android:id="#+id/navDrawerImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:paddingRight="10dp"/>
<TextView
android:id="#+id/navDrawerTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="#+id/navDrawerImageView"
android:paddingRight="10dp"
android:textAppearance="?android:attr/textAppearanceListItemSmall"/>
</RelativeLayout>
In MainActivity.java, instantiate an array of NavDrawerItem objects, with the appropriate drawable and name for each, and then pass this array when you set the adapter, like so:
mDrawerList.setAdapter(new YourAdapter(this, R.layout.drawer_list_item, yourArray));
Updated
1) I don't see the source of data to be displayed in your code - you don't pass it in the constructor or any other way
2) In getView() you should set values for your Views
3) To be efficient you have to re-use convertView if it's not null
4) And at last - for your CustomAdapter override also following methods:
#Override
public int getViewTypeCount() {
...
}
#Override
public int getItemViewType(int position) {
...
}
#Override
public int getCount() {
...
}
#Override
public YOUR_ITEM_TYPE getItem(int position) {
...
}
#Override
public long getItemId(int position) {
...
}
#Override
public boolean hasStableIds() {
...
}
#Override
public boolean isEmpty() {
...
}
#Override
public boolean areAllItemsEnabled() {
...
}
#Override
public boolean isEnabled(int position) {
...
}
In my app there is a Main Acitvity (which extends List Activity) where I have one list view. I want to make items of this list view clickable and handle click events. Here's my code:
public class MainActivity extends ListActivity {
private ArrayList<Item> m_parts = new ArrayList<Item>();
private ItemAdapter m_adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
(…)
m_adapter = new ItemAdapter(this, R.layout.item_layout, m_parts);
setListAdapter(m_adapter);
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
(…)
}
}
And here's my xml for Main Activity layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/main_background"
tools:context=".MainActivity">
<ListView
android:id="#+id/android:list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
</ListView>
</LinearLayout>
This is my Item class:
public class Item {
private Bitmap image;
private Uri uri;
private String title;
private String date;
private String latitude;
private String longitude;
public CheckBox checkBox = null;
public Item(){}
public Item(Bitmap bi, Uri ur, String ti, String da, String la, String lo){
this.image = bi;
this.uri = ur;
this.title = ti;
this.date = da;
this.latitude = la;
this.longitude = lo;
}
public Bitmap getImage() {return image;}
public String getTitle(){
return title;
}
public String getDate(){
return date;
}
public String getLatitude(){
return latitude;
}
public String getLongitude(){
return longitude;
}
public Boolean isChecked(){
return checkBox.isChecked();
};
public Uri getUri(){
return uri;
}
}
Item's layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight">
<ImageView
android:id="#+id/photo"
android:layout_width="60dp"
android:layout_height="?android:attr/listPreferredItemHeight"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:scaleType="fitXY"/>
<TextView
android:id="#+id/place"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="#+id/photo"
android:textColor="#color/white"
android:textColorHighlight="#color/white"
android:textColorHint="#color/white"
android:textColorLink="#color/white"
android:hint="#string/founding_place_text" />
<TextView
android:id="#+id/date"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_toRightOf="#+id/photo"
android:textColor="#color/white"
android:textColorHighlight="#color/white"
android:textColorHint="#color/white"
android:textColorLink="#color/white"
android:hint="#string/founding_date_text" />
<TextView
android:id="#+id/title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toRightOf="#+id/photo"
android:maxLines="1"
android:textColor="#color/white"
android:textColorHighlight="#color/white"
android:textColorHint="#color/white"
android:textColorLink="#color/white"
android:hint="#string/founding_title_text_2" />
<CheckBox
android:id="#+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"/>
</RelativeLayout>
And eventually my Item Adapter:
public class ItemAdapter extends ArrayAdapter<Item>{
private ArrayList<Item> objects;
public ItemAdapter(Context context, int textViewResourceId, ArrayList<Item> objects){
super(context, textViewResourceId, objects);
this.objects = objects;
}
public View getView(int position, View convertView, ViewGroup parent){
View v = convertView;
if(v == null){
LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.item_layout, null);
}
Item i = objects.get(position);
if(i != null){
ImageView im = (ImageView)v.findViewById(R.id.photo);
TextView ti = (TextView)v.findViewById(R.id.title);
TextView da = (TextView)v.findViewById(R.id.date);
TextView pl = (TextView)v.findViewById(R.id.place);
CheckBox ch = (CheckBox)v.findViewById(R.id.checkBox);
if(im != null){
im.setImageBitmap(i.getImage());
}
if(ti != null){
if(i.getTitle() != null && i.getTitle() != ""){
ti.setText(i.getTitle());
}else{
ti.setText("No title");
}
}
if(da != null){
da.setText(i.getDate());
}
if(pl != null){
if(i.getLatitude()!=null && i.getLongitude()!=null){
pl.setText(i.getLatitude() + ", " + i.getLongitude());
}else{
pl.setText("No coordinates");
}
}
if(ch != null){
i.checkBox = ch;
}
}
return v;
}
}
My problem is that onListItemClick(…) isn't called when I click on any item in list view. What's more, they aren't even highlighted. Do you have any idea what do I have to add to my code to handle click events? I am using Android 4.3.
Don't set your list view to be clickable and don't set an OnItemClickListener. (In other words, end your onCreate() method with the call to setlistAdapter.) You only need to override onListItemClicked; the ListActivity infrastructure takes care of the rest. By setting a listener yourself you are interfering with the framework's mechanism.
remove android:clickable="true" from layout and listView.setClickable(true) from code and set listView.setOnItemClickListener and put android:layout_height="wrap_content" android:layout_width="match_parent
I have a question, currently I am using CursorTreeAdapter however I want to change it to use any other data not just cursors, but to be honest im not sure how would I do that, I think implement some other adapter and then override needed methods? But could any one show me some way? I'm confused right now and don't know to what direction I should go.
Thanks for help.
Abstract classes you can extend: BaseAdapter ArrayAdapter.
You can see this example:
public class FeedAdapter extends BaseAdapter {
private ArrayList<FeedItem> items;
private LayoutInflater layoutInflater;
FeedAdapter(Context context, ArrayList<FeedItem> list, int bgColor){
items = list;
layoutInflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return items.size();
}
#Override
public FeedItem getItem(int index) {
return items.get(index);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row;
if (null == convertView) {
row = layoutInflater.inflate(R.layout.romanblack_feed_item, null);
} else {
row = convertView;
}
TextView title = (TextView) row.findViewById(R.id.romanblack_rss_title);
TextView pubdate = (TextView) row.findViewById(R.id.romanblack_rss_pubdate);
String titleString = items.get(position).getTitle();
title.setText(titleString);
if(items.get(position).getTextColor() != Color.TRANSPARENT){
title.setTextColor(items.get(position).getTextColor());
}else{
title.setTextColor(Color.DKGRAY);
}
pubdate.setText(items.get(position).getPubdate());
return row;
}
}
and layout file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/romanblack_feed_item"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#FFF">
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/romanblack_rss_bg_feed"
android:orientation="vertical">
<TextView
android:text="Title"
android:id="#+id/romanblack_rss_title"
android:textSize="14sp"
android:textColor="#222"
android:layout_margin="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:text="2011-01-01"
android:id="#+id/romanblack_rss_pubdate"
android:textSize="10sp"
android:textColor="#666"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
I wanna create a customized ListView like this:
I think that I have to use BaseAdapter but I have no idea about it.
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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<ListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" >
</ListView>
</RelativeLayout>
custom.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="255dp"
android:layout_height="wrap_content"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Video1"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#339966"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/detail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="video1"
android:textColor="#606060" />
</LinearLayout>
</LinearLayout>
<ImageView
android:id="#+id/img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_launcher" />
</LinearLayout>
</LinearLayout>
main.java:
package com.example.sample;
import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
public class MainActivity extends Activity {
ListView l1;
String[] t1={"video1","video2"};
String[] d1={"lesson1","lesson2"};
int[] i1 ={R.drawable.ic_launcher,R.drawable.ic_launcher};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
l1=(ListView)findViewById(R.id.list);
l1.setAdapter(new dataListAdapter(t1,d1,i1));
}
class dataListAdapter extends BaseAdapter {
String[] Title, Detail;
int[] imge;
dataListAdapter() {
Title = null;
Detail = null;
imge=null;
}
public dataListAdapter(String[] text, String[] text1,int[] text3) {
Title = text;
Detail = text1;
imge = text3;
}
public int getCount() {
// TODO Auto-generated method stub
return Title.length;
}
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return null;
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = getLayoutInflater();
View row;
row = inflater.inflate(R.layout.custom, parent, false);
TextView title, detail;
ImageView i1;
title = (TextView) row.findViewById(R.id.title);
detail = (TextView) row.findViewById(R.id.detail);
i1=(ImageView)row.findViewById(R.id.img);
title.setText(Title[position]);
detail.setText(Detail[position]);
i1.setImageResource(imge[position]);
return (row);
}
}
}
Try this.
public class ListElementAdapter extends BaseAdapter{
String[] data;
Context context;
LayoutInflater layoutInflater;
public ListElementAdapter(String[] data, Context context) {
super();
this.data = data;
this.context = context;
layoutInflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return data.length;
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView= layoutInflater.inflate(R.layout.item, null);
TextView txt=(TextView)convertView.findViewById(R.id.text);
txt.setText(data[position]);
return convertView;
}
}
Just call ListElementAdapter in your Main Activity and set Adapter to ListView.
Create your own BaseAdapter class and use it as following.
public class NotificationScreen extends Activity
{
#Override
protected void onCreate_Impl(Bundle savedInstanceState)
{
setContentView(R.layout.notification_screen);
ListView notificationList = (ListView) findViewById(R.id.notification_list);
NotiFicationListAdapter notiFicationListAdapter = new NotiFicationListAdapter();
notificationList.setAdapter(notiFicationListAdapter);
homeButton = (Button) findViewById(R.id.home_button);
}
}
Make your own BaseAdapter class and its separate xml file.
public class NotiFicationListAdapter extends BaseAdapter
{
private ArrayList<HashMap<String, String>> data;
private LayoutInflater inflater=null;
public NotiFicationListAdapter(ArrayList data)
{
this.data=data;
inflater =(LayoutInflater)baseActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount()
{
return data.size();
}
public Object getItem(int position)
{
return position;
}
public long getItemId(int position)
{
return position;
}
public View getView(int position, View convertView, ViewGroup parent)
{
View vi=convertView;
if(convertView==null)
vi = inflater.inflate(R.layout.notification_list_item, null);
ImageView compleatImageView=(ImageView)vi.findViewById(R.id.complet_image);
TextView name = (TextView)vi.findViewById(R.id.game_name); // name
TextView email_id = (TextView)vi.findViewById(R.id.e_mail_id); // email ID
TextView notification_message = (TextView)vi.findViewById(R.id.notification_message); // notification message
compleatImageView.setBackgroundResource(R.id.address_book);
name.setText(data.getIndex(position));
email_id.setText(data.getIndex(position));
notification_message.setTextdata.getIndex(position));
return vi;
}
}
BaseAdapter xml file.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/inner_layout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginLeft="10dp"
android:layout_weight="4"
android:background="#drawable/list_view_frame"
android:gravity="center_vertical"
android:padding="5dp" >
<TextView
android:id="#+id/game_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Game name"
android:textColor="#FFFFFF"
android:textSize="15dip"
android:textStyle="bold"
android:typeface="sans" />
<TextView
android:id="#+id/e_mail_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/game_name"
android:layout_marginTop="1dip"
android:text="E-Mail Id"
android:textColor="#FFFFFF"
android:textSize="10dip" />
<TextView
android:id="#+id/notification_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/game_name"
android:layout_toRightOf="#id/e_mail_id"
android:paddingLeft="5dp"
android:text="Notification message"
android:textColor="#FFFFFF"
android:textSize="10dip" />
<ImageView
android:id="#+id/complet_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginBottom="30dp"
android:layout_marginRight="10dp"
android:src="#drawable/complete_tag"
android:visibility="invisible" />
</RelativeLayout>
Change it accordingly and use.
I suggest using a custom Adapter, first create a Xml-file, for example layout/customlistview.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" >
<ImageView
android:id="#+id/image"
android:layout_alignParentRight="true"
android:paddingRight="4dp" />
<TextView
android:id="#+id/title"
android:layout_toLeftOf="#id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="23sp"
android:maxLines="1" />
<TextView
android:id="#+id/subtitle"
android:layout_toLeftOf="#id/image" android:layout_below="#id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
Assuming you have a custom class like this
public class CustomClass {
private long id;
private String title, subtitle, picture;
public CustomClass () {
}
public CustomClass (long id, String title, String subtitle, String picture) {
this.id = id;
this.title= title;
this.subtitle= subtitle;
this.picture= picture;
}
//add getters and setters
}
And a CustomAdapter.java uses the xml-layout
public class CustomAdapter extends ArrayAdapter {
private Context context;
private int resource;
private LayoutInflater inflater;
public CustomAdapter (Context context, List<CustomClass> values) { // or String[][] or whatever
super(context, R.layout.customlistviewitem, values);
this.context = context;
this.resource = R.layout.customlistview;
this.inflater = LayoutInflater.from(context);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView = (RelativeLayout) inflater.inflate(resource, null);
CustomClass item = (CustomClass) getItem(position);
TextView textviewTitle = (TextView) convertView.findViewById(R.id.title);
TextView textviewSubtitle = (TextView) convertView.findViewById(R.id.subtitle);
ImageView imageview = (ImageView) convertView.findViewById(R.id.image);
//fill the textviews and imageview with the values
textviewTitle = item.getTtile();
textviewSubtitle = item.getSubtitle();
if (item.getAfbeelding() != null) {
int imageResource = context.getResources().getIdentifier("drawable/" + item.getImage(), null, context.getPackageName());
Drawable image = context.getResources().getDrawable(imageResource);
}
imageview.setImageDrawable(image);
return convertView;
}
}
Did you manage to do it? Feel free to ask if you want more info on something :)
EDIT: Changed the adapter to suit a List instead of just a List
private class ObjectAdapter extends BaseAdapter {
private Context context;
private List<Object>objects;
public ObjectAdapter(Context context, List<Object> objects) {
this.context = context;
this.objects = objects;
}
#Override
public int getCount() {
return objects.size();
}
#Override
public Object getItem(int position) {
return objects.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView==null){
holder = new ViewHolder();
convertView = LayoutInflater.from(context).inflate(android.R.layout.simple_list_item_1, parent, false);
holder.text = (TextView) convertView.findViewById(android.R.id.text1);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
holder.text.setText(getItem(position).toString()));
return convertView;
}
class ViewHolder {
TextView text;
}
}