Thursday, May 10, 2018

Change background of custom drawable

1.listbox_bg.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@+id/listbg">
    <shape android:shape="rectangle" >
        <stroke
            android:width="2dip"
            android:color="#ffffff" />
        <solid android:color="#0000"/>
    </shape>
</item>
</layer-list>


2.MainActivity.java

Drawable tempDrawable = getResources().getDrawable(R.drawable.listbox_bg);
LayerDrawable bubble = (LayerDrawable) tempDrawable;
GradientDrawable solidColor = (GradientDrawable) bubble.findDrawableByLayerId(R.id.listbg);
solidColor.setColor(Color.parseColor(colorCode));

ListView custom item with RadioButton

Creating ListView that has RadioButton in ListView custom item.

Here are the key ideas
  • when a RadioButton is checked we must call notifyDataSetChanged(), so that all views get updated.
  • when a RadioButton is checked we must set a selectedPosition, to keep track of which RadioButton is selected
  • Views are recycled inside ListViews. Therefore, their absolute position changes in the ListView. Therefore, inside ListAdapter#getView(), we must call setTag() on each RadioButton. This allows us to determine the current position of the RadioButton in the list when the RadioButton is clicked.
  • RadioButton#setChecked() must be updated inside getView() for new or pre-existing Views.

1.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="wrap_content"
    android:id="@+id/ll_parent">

    <RadioButton
        android:id="@+id/radio"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:clickable="false"/>

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:clickable="false"/>
</LinearLayout>

To make RadioButton works correctly when click, you need to set android:clickable="false" to child elements.

2.activity_list_view_custom_item_with_radio_button.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <ListView
        android:id="@+id/listView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:choiceMode="singleChoice"/>

</LinearLayout>

3.ListViewCustomItemWithRadioButtonActivity.java

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RadioButton;
import android.widget.TextView;

import java.util.ArrayList;

public class ListViewCustomItemWithRadioButtonActivity extends AppCompatActivity {

    private int selected_pos = -1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_list_view_custom_item_with_radio_button);

        ListView listView = (ListView) findViewById(R.id.listView);

        ArrayList<String> arrayList = new ArrayList<>();
        for (int i = 0 ; i < 50; i++){
            arrayList.add("Item : " + (i + 1));
        }

        MyAdapter arrayAdapter = new MyAdapter(arrayList);
        listView.setAdapter(arrayAdapter);
    }

    private class MyAdapter extends BaseAdapter {

        private ArrayList< String>arrayList;

        private MyAdapter(ArrayList< String>arrayList){
            this.arrayList = arrayList;
        }

        @Override
        public int getCount() {
            return arrayList.size();
        }

        @Override
        public Object getItem(int position) {
            return arrayList.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            View view = convertView;
            if (view == null){
                view = View.inflate(ListViewCustomItemWithRadioButtonActivity.this, R.layout.row, null);
            }
            final LinearLayout ll_parent = (LinearLayout) view.findViewById(R.id.ll_parent);
            final RadioButton radioButton = (RadioButton) view.findViewById(R.id.radio);
            radioButton.setText(arrayList.get(position));
            radioButton.setChecked(position == selected_pos);
            radioButton.setTag(position);
            ll_parent.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    selected_pos = (Integer) v.findViewById(R.id.radio).getTag();
                    notifyDataSetChanged();
                }
            });
            TextView textView = (TextView) view.findViewById(R.id.text);
            textView.setText("Position : ".concat(String.valueOf(position)));

            return view;
        }
    }
}