Setting background programmatically overrides drawable - android

I have a ListView and I have a Drawable for each item in the ListView to highlight each row when it's selected/pressed. I also have a custom adapter where I'm programatically setting the background color of each row (I want to have alternating background colors). This is a new feature I added and before adding the code the rows would highlight blue, but after they do not highlight. Not sure how to fix it. Here is what I have:
ListView item 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="fill_parent"
android:orientation="vertical"
android:paddingLeft="5dip"
android:paddingRight="5dip"
android:paddingTop="8dip"
android:paddingBottom="8dip"
android:background="#drawable/app_selector"
>
<TextView
android:id="#+id/text"
style="#style/ListingTitle"
android:layout_alignParentTop="true"
android:paddingBottom="2dip"
/>
</RelativeLayout>
Drawable
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="#color/light_blue" />
<item android:state_selected="true" android:state_pressed="false" android:drawable="#color/light_blue" />
<item android:state_activated="true" android:state_selected="false" android:state_pressed="false" android:drawable="#color/light_blue" />
<item android:state_selected="false" android:state_pressed="false" android:drawable="#android:color/transparent" />
</selector>
Fragment
public class ListingFragment extends SherlockListFragment
{
public void onActivityCreated(final Bundle icicle)
{
ListView lv = getListView();
mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
mListView.setMultiChoiceModeListener(new MultiChoiceModeListener() {
#Override
public void onItemCheckedStateChanged(android.view.ActionMode mode, int position, long id, boolean checked) {
}
#Override
public boolean onActionItemClicked(android.view.ActionMode mode, android.view.MenuItem item) {
}
}
}
/* ADAPTER */
private class CustomAdapter extends BaseAdapter
{
#Override
public View getView(final int position, View convertView, final ViewGroup parent)
{
final ViewHolder holder;
if (convertView == null)
{
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.item, parent, false);
}
else
{
holder = (ViewHolder)convertView.getTag();
}
if (position % 2 == 0)
convertView.setBackgroundColor(Color.GRAY);
else
convertView.setBackgroundColor(Color.TRANSPARENT);
return(convertView);
}
}
}

Expanding on dum's answer, you don't need to do all that work in code.
Drawable A
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="#color/light_blue" />
<item android:state_selected="true" android:state_pressed="false" android:drawable="#color/light_blue" />
<item android:state_activated="true" android:state_selected="false" android:state_pressed="false" android:drawable="#color/light_blue" />
<item android:state_selected="false" android:state_pressed="false" android:drawable="#android:color/transparent" />
</selector>
Drawable B
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="#color/light_blue" />
<item android:state_selected="true" android:state_pressed="false" android:drawable="#color/light_blue" />
<item android:state_activated="true" android:state_selected="false" android:state_pressed="false" android:drawable="#color/light_blue" />
<item android:state_selected="false" android:state_pressed="false" android:drawable="#android:color/gray" />
</selector>
In your Adapter:
if (position % 2 == 0) {
convertView.setBackgroundResource(R.drawable.A);
} else {
convertView.setBackgroundResource(R.drawable.B);
}

instead of changing the drawable with plain color, first create a new drawable programmatically and set the states just like in your xml and then set colors for each state. then try replacing your background with your programmatically created drwable.

Related

Make ListView Item Selection remain Stable

How to make ListView Item Selection remain stable ?
<ListView
android:id="#+id/list_slidermenu"
android:layout_height="0dp"
android:layout_width="match_parent"
android:layout_weight="8"
android:layout_gravity="start"
android:scrollbars="none"
android:fastScrollEnabled="true"
android:choiceMode="singleChoice"
/>
You've to make getSelectedIndex() and setSelectedIndex() method in your adapter.
private int selectedIndex;
public int getSelectedIndex() {
return selectedIndex;
}
public void setSelectedIndex(int index) {
this.selectedIndex = index;
// Re-draw the list by informing the view of the changes
notifyDataSetChanged();
}
and then
#Override
public View getView(int position, View convertView, ViewGroup parent) {
.......
// Highlight the selected item in the list
if (selectedIndex != -1 && selectedIndex == position) {
v.setBackgroundResource(R.color.yourColor);
}
return v;
}
and used from onListItemClick(....)
adapter.setSelectedIndex(position);
Another way as #Sun said
Used gradient to make list selection remain stable
gradient_bg.xml:-
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="#7ecce8"
android:centerColor="#7ecce8"
android:endColor="#7ecce8"
/>
</shape>
gradient_bg_hover.xml:-
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="#7ecce8"
android:centerColor="#7ecce8"
android:endColor="#7ecce8"
/>
</shape>
list_selector.xml:-
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_selected="false"
android:state_pressed="false"
android:drawable="#drawable/gradient_bg" />
<item android:state_pressed="true"
android:drawable="#drawable/gradient_bg_hover" />
<item android:state_selected="true"
android:state_pressed="false"
android:drawable="#drawable/gradient_bg_hover" />
</selector>
finally in ListView, use listSelector property like below:
android:listSelector="#drawable/list_selector"
I have used gradient to make list selection remain stable
gradient_bg.xml:-
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="#7ecce8"
android:centerColor="#7ecce8"
android:endColor="#7ecce8"
/>
</shape>
gradient_bg_hover.xml:-
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="#7ecce8"
android:centerColor="#7ecce8"
android:endColor="#7ecce8"
/>
</shape>
list_selector.xml:-
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_selected="false"
android:state_pressed="false"
android:drawable="#drawable/gradient_bg" />
<item android:state_pressed="true"
android:drawable="#drawable/gradient_bg_hover" />
<item android:state_selected="true"
android:state_pressed="false"
android:drawable="#drawable/gradient_bg_hover" />
</selector>
finally in ListView, use listSelector property like below:
android:listSelector="#drawable/list_selector"
You need to keep track of selected item and accordingly change the background of the list row.
1.Change the selected item's position in item click :
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1,int position, long arg3) {
adapter.setSelectedItem(position);
}
2.Get selected item and set background :
public class AudioAdapter extends ArrayAdapter<Audio> {
Integer selected_position = -1;
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Your Code
if (position == selected_position) {
// set selected color
v.setBackgroundResource(R.color.yourSelectedColor);
} else {
// set default color
v.setBackgroundResource(R.color.yourDefaultColor);
}
}
public int getSelectedItem() {
return selected_position;
}
public void setSelectedItem(int index) {
this.selected_position = index;
}
}
Hope it helps ツ

Highlight ListItem when it is clicked in listview in android

I want to highlight the list item when it is clicked.I have written the below code but it is not working.I want the particular item in the listview to be clicked.
MainActivity.java
ListView lv = getListView();
lv.setSelector( R.drawable.list_selector);
// on selecting single product
// launching Edit Product Screen
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// getting values from selected ListItem
String FC_DATE = ((TextView) view.findViewById(R.id.fc_date)).getText()
.toString();
// Starting new intent
Intent in = new Intent(getApplicationContext(),
ForecastActivity.class);
// sending lat/long to next activity
in.putExtra(TAG_FC_DATE, FC_DATE);
in.putExtra(TAG_LAT, LAT);
in.putExtra(TAG_LONG, LONGITUDE);
// starting new activity and expecting some response back
startActivityForResult(in, 100);
}
});
list_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Selector style for listrow -->
<item
android:state_selected="false"
android:state_pressed="false"
android:drawable="#drawable/gradient_bg" />
<item android:state_pressed="true"
android:drawable="#drawable/gradient_bg_hover" />
<item android:state_selected="true"
android:state_pressed="false"
android:drawable="#drawable/gradient_bg_hover" />
</selector>
listitem_selector.xml :
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_enabled="true"
android:state_pressed="true" android:drawable="#drawable/gradient_bg_hover" />
<item android:state_enabled="true"
android:state_focused="true" android:drawable="#drawable/gradient_bg_hover" />
<item android:state_enabled="true"
android:state_selected="true" android:drawable="#drawable/gradient_bg_hover" />
<item
android:drawable="#drawable/gradient_bg" />
</selector>
Set list item selector to ListView :
<ListView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:listSelector="#drawable/listitem_selector" />

Android how to Change Default background color in Button click?

I need to show different color on button after click because user need to know button is
Click.
I don't understand how to do this?
Give me suggestion. button click shoud be programatically, No Need to create XML for this
//XML file saved at res/drawable/button_bg.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:color="#ffff0000"/> <!-- pressed -->
<item android:state_focused="true"
android:color="#ff0000ff"/> <!-- focused -->
<item android:color="#ff000000"/> <!-- default -->
</selector>
in JAVA
am create like this
Button Settings_Button = new Button(this) ;
Settings_Button.setClickable(true);
//Settings_Button.setBackgroundResource(R.drawable.selector);
Settings_Button.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
// Intent newIntent = new Intent(activity.getBaseContext(), ProfileSettingActivity.class);
// activity.startActivity(newIntent);
}
});
BUt this is not working
EDIT : How to change Background color when click button in programatically.
try this way,hope this will help you...
button_selector
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/button_pressed" android:state_pressed="true"></item>
<item android:drawable="#color/button_pressed" android:state_focused="true"></item>
<item android:drawable="#color/button_default" android:state_enabled="true" android:state_focused="false" android:state_pressed="false"></item>
<item android:drawable="#color/button_pressed" android:state_enabled="false"></item>
</selector>
color
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="button_pressed">#ffff0000</color>
<color name="button_default">#ff0000ff</color>
</resources>
ACTIVITY code
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn = new Button(this);
btn.setBackgroundResource(R.drawable.button_selector);
btn.setText("Custom Button");
addContentView(btn,new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
}
Create selector drawable according all state.
Below is sample example.
btn_green_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_focused="false"
android:state_selected="false"
android:state_pressed="false"
android:drawable="#drawable/btn_green_unselected" />
<item
android:state_focused="true"
android:state_selected="false"
android:state_pressed="false"
android:drawable="#drawable/btn_green_selected" />
<!-- Focused states -->
<item
android:state_focused="true"
android:state_selected="true"
android:state_pressed="false"
android:drawable="#drawable/btn_green_selected" />
<!-- Pressed state -->
<item
android:state_pressed="true"
android:drawable="#drawable/btn_green_selected" />
</selector>
btn_green_selected.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#00B2B2"/>
</shape>
btn_green_unselected.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#8ED3CD"/>
</shape>
now applied btn_green_selector.xml in coding.
Settings_Button.setBackgroundResource(R.drawable.btn_green_selector);
you can also use Images instead of Shape.
Try Like this,
main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/myLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="64dp"
android:layout_marginTop="71dp"
android:text="changeColor" />
</LinearLayout>
ChangeBackgroundActivity.java
public class ChangeBackgroundActivity extends Activity {
/** Called when the activity is first created. */
Button blueButton;
LinearLayout myLO;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myLO=(LinearLayout)findViewById(R.id.myLayout);
blueButton=(Button)findViewById(R.id.button1);
blueButton.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
// TODO Auto-generated method stub
myLO.setBackgroundColor(Color.BLUE);
}
});
}
}
You can use this line in buttons onclicklistener,button.setBackgroundColor(Color.WHITE);

How do I ensure change the background of a selected GridView cell?

In Android, I have a GridView - each cell in the GridView is an ImageView. When a user clicks on a cell, I would like that cell to be "selected" (have its background turn blue), and all other cells to "unselect" (have their backgrounds turn white).
I have implemented the following background drawable, but it only changes the background while the cell is pressed:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="#drawable/iconborder_selected" /> <!-- pressed -->
<item android:drawable="#drawable/iconborder_unselected" /> <!-- default -->
</selector>
EDIT: Here is my adapter code for the GridView.
class IconAdapter extends BaseAdapter {
private Context context = null;
private List<Drawable> icons = new ArrayList<Drawable>();
public IconAdapter(Context context) {
this.context = context;
for (Field f : R.drawable.class.getFields()) {
String path = f.getName();
if (path.contains("icon_")) {
int id = context.getResources().getIdentifier(path, "drawable",
context.getPackageName());
Drawable drawable = context.getResources().getDrawable(id);
icons.add(drawable);
}
}
}
#Override
public int getCount() {
return icons.size();
}
#Override
public Object getItem(int position) {
return icons.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView iv = new ImageView(context);
iv.setImageDrawable(icons.get(position));
iv.setBackgroundResource(R.drawable.iconborder);
return iv;
}
}
You should add state_selected too:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true"
android:drawable="#drawable/iconborder_selected" /> <!-- selected -->
<item android:state_pressed="true"
android:drawable="#drawable/iconborder_pressed" /> <!-- pressed -->
<item android:state_pressed="false"
android:drawable="#drawable/iconborder_unselected" /> <!-- default -->
</selector>
Try in the XML declaration of the GridView to put these lines:
<GridView
<!-- Some stuff here, like id, width, e.t.c. -->
android:drawSelectorOnTop="true"
android:listSelector="path_to_your_selector"
/>
And your selector should contain something like this:
<item android:state_pressed="true">
<shape>
<!-- Or a drawable here -->
</shape>
</item>
<item android:state_focused="true">
<shape>
<!-- Or a drawable here -->
</shape>
</item>
<item android:drawable="#android:color/transparent" />

Android Custom ListView with Checkbox and changing background color

I have a custom ListView with Checkboxes and 3 TextViews. Here is my layout for list item:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/listviewitem_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<CheckBox
android:id="#+id/faxCheckBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="false"
android:focusableInTouchMode="false" />
<LinearLayout android:orientation="horizontal"
android:id="#+id/faxbox_item_first_row"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/faxCheckBox"
android:paddingTop="8dp"
android:paddingLeft="8dp"
android:paddingRight="8dp">
<TextView android:id="#+id/fax_number_textView"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:lines="1"
android:ellipsize="start"
android:textSize="12sp"
android:paddingRight="5dp"/>
<TextView android:id="#+id/fax_send_date_textView"
android:layout_width="wrap_content"
android:layout_weight="0"
android:layout_height="wrap_content"
android:textSize="9sp"/>
</LinearLayout>
<TextView android:id="#+id/more_fax_info_textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="9sp"
android:textColor="#color/gray"
android:layout_toRightOf="#id/faxCheckBox"
android:layout_below="#id/faxbox_item_first_row"
android:paddingLeft="8dp"/>
</RelativeLayout>
I have also a custom arrayadapter for the listview:
private class MyAdapter extends ArrayAdapter<Order> {
private ArrayList<Order> mOrders;
private Context mContext;
private int mResourceId;
public MyAdapter(Context context, int resourceId, ArrayList<Order> orders) {
super(context, resourceId, orders);
this.mContext = context;
this.mOrders = orders;
this.mResourceId = resourceId;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
LayoutInflater vi = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = vi.inflate(mResourceId, parent, false);
}
final Order order = mOrders.get(position);
if (order != null) {
TextView sender = (TextView)view.findViewById(R.id.number_textView);
TextView date = (TextView)view.findViewById(R.id.send_date_textView);
TextView moreInfo = (TextView)view.findViewById(R.id.more_info_textView);
CheckBox checkBox = (CheckBox)view.findViewById(R.id.checkBox);
final int itemPosition = position;
final RelativeLayout rowLayout = (RelativeLayout)view.findViewById(R.id.listviewitem_layout);
view.setTag(order.getId());
if (sender != null) {
sender.setText(order.getSender());
}
rowLayout.setBackgroundResource(R.drawable.listview_item_selector);
if (mSelectedIds.contains(order.getId())) {
rowLayout.setBackgroundColor(Color.parseColor("#9CD7EF"));
}
if (date != null) {
date.setText(Utils.getStringDateForBox(order.getSendDate(), mContext));
}
if (moreInfo != null) {
moreInfo.setText(getResources().getQuantityString(R.plurals.number_of_pages, order.getPages(), order.getPages()));
}
if (checkBox != null) {
checkBox.setTag(order.getId());
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (mSelectedIds.contains(buttonView.getTag()) == true) {
if (isChecked == false) {
mSelectedIds.remove(buttonView.getTag());
}
} else {
if (isChecked) {
mSelectedIds.add((Long) buttonView.getTag());
}
}
showHideActionMode();
setActionModeTitle();
mListView.setItemChecked(position, true);
}
});
if (mSelectedIds.contains(order.getId())) {
checkBox.setChecked(true);
} else {
checkBox.setChecked(false);
}
}
}
return view;
}
}
listview_item_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true"
android:drawable="#color/blue" />
<item android:state_pressed="true"
android:drawable="#color/blue" />
<item android:state_selected="true"
android:state_activated="true"
android:drawable="#color/light_blue" />
<item android:state_activated="true"
android:drawable="#color/light_blue" />
<item android:state_selected="true"
android:drawable="#color/light_blue" />
<item android:state_focused="false" android:state_selected="false" android:state_pressed="false"
android:drawable="#android:color/white" />
<item android:drawable="#android:color/transparent" />
</selector>
The problem is, if I press a row, then it changes the background color to blue, but without checkbox, checbox has all the time the orange background color. How can I change it?
Maybe should I everything differently make? I'd like at the best something like in the gmail app on the ICS.
I find only how to make a custom checkbox, but this is not the best solution.
checbox_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true"
android:drawable="#drawable/btn_check_off_pressed_holo_light" />
<item android:state_checked="true"
android:state_pressed="true"
android:drawable="#drawable/btn_check_on_pressed_holo_light" />
<item android:state_pressed="true"
android:drawable="#drawable/btn_check_off_pressed_holo_light" />
<item android:state_checked="true"
android:state_activated="true"
android:drawable="#drawable/btn_check_on_holo_light" />
<item android:state_activated="true"
android:drawable="#drawable/btn_check_on_holo_light" />
<item android:state_checked="true"
android:drawable="#drawable/btn_check_on_holo_light" />
<item android:state_focused="false" android:state_selected="false" android:state_pressed="false"
android:drawable="#drawable/btn_check_off_holo_light" />
<item android:drawable="#drawable/btn_check_off_holo_light" />
and in my list item layout I added that to my checkbox:
android:button="#drawable/checkbox_selector"

Categories

Resources