I have a ListView which contains custom rows. This custom row has following UI elements
The requirement is whenever the list row is SELECTED there would be following changes
imageView1 background,color is changed
imageView1 color is changed
textview1 color,size and typeface is changes
textview2 color,size is changed
textview3 color,size is changed
What would be the best way to design for this?
AFAIK we cannot apply styles in the selector. Is there a better way to work on this rather than handling in the java code?
We have setOnItemSelectedListener that can be set on a Listview which would have following callback methods:
i) onItemSelected
ii) onNothingSelected
However there is no callback method which provide details of the item which has lost its focus. Is this a better place to make the changes?
Thanks in advance.
I think what you want to do here is create a Compound Control. You can find an example in your SDK directory in the samples//ApiDemos subdirectory (you may want to download the Android source if you don't have these directories).
What I would do is create a class that inherits from whatever kind of layout you are using for your custom row. Let's suppose it's a LinearLayout
for this example. In your subclass constructor, you can inflate your layout from a resource, find the subViews and attach them to instance variables, and return the LinearLayout to the caller.
In this subclass, you can override setSelected
and manipulate the subViews in whatever way you want.
Here's an example of what I am describing based on your post:
public class MyCustomLayout extends LinearLayout {
public ImageView imageView1; // These are public since you likely want
public ImageView imageView2; // to set them in your Adapter.
public TextView textView1;
public TextView textView2;
public TextView textView3;
public MyCustomLayout(Context ctxt) {
super(ctxt);
// The call below attaches the items in the mycustomlayout.xml file to this
// instance, which serves as the root element in the layout.
LayoutInflater.from(ctxt).inflate(R.layout.mycustomlayout, this, true);
imageView1 = (ImageView)findViewById(R.id.imageview1);
imageView2 = (ImageView)findViewById(R.id.imageview2);
textView1 = (TextView)findViewById(R.id.textview1);
textView2 = (TextView)findViewById(R.id.textview2);
textView3 = (TextView)findViewById(R.id.textview3);
}
@Override
public void setSelected(boolean selected) {
super.setChecked(selected);
if (selected) {
imageView1.setBackgroundColor(0xFFFF0000); // whatever color you want
// Do all the rest of the setting of your subviews here for
// the case when the row is selected.
} else {
imageView1.setBackgroundColor(0xFF000000); // whatever color you want
// Do all the rest of the setting of your subviews here for
// the case when the row is not selected
}
}
}
Now, in the mycustomlayout.xml file, you want to use the <merge>
tag so that you don't create an unneeded layout:
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<ImageView
android:id="@+id/imageview1" />
<ImageView
android:id="@+id/imageview2" />
<TextView
android:id="@+id/textview1" />
<TextView
android:id="@+id/textview2" />
<TextView
android:id="@+id/textview3" />
</merge>
I've elided all the configuration of the subviews above, obviously, but you should get the idea about how to set up the XML file. You could also do this in code if you don't want to fool with XML and a LayoutInflater. You can look at this helpful blog post on the Android dev blog which discusses a similar case towards the end.
Then, in your Adapter's getView
you can just create (or recycle) instances of MyCustomLayout
, set them up, and let the framework take care of keeping track of which rows are selected and which aren't selected.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With