DRY approach on android - android

During development of Android application, I noticed that I use multiple buttons, that the different between them is the Id, the text and the onclick function.
So I implemented a different XML file holding 1 styled button, and when I want to use a button I just import it into the required layout.
But then I realized I have a new problem: I don't know how to set all the different parameters at each imported button...
Is there a method to perform this and stick to DRY approach?

Well, if you need multiple buttons, you will need to give them different identifiers. You can do this in your import declaration like this:
<include layout="#layout/your_button"
android:id="#+id/loginButton" />
Then, you can reference them by ID like usual:
Button loginButton = (Button) findViewById(R.id.loginButton);
loginButton.setText("Login");
However, I am not sure this is a better approach than just declaring your buttons as needed in XML. If you want to avoid repeating styling, you can define a custom style for your button and apply it in the XML declaration. See the docs on styling for more information.
Below is an example from the docs with an EditText.
In the styles:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="CustomText" parent="#style/Text">
<item name="android:textSize">20sp</item>
<item name="android:textColor">#008</item>
</style>
</resources>
In your layout:
<?xml version="1.0" encoding="utf-8"?>
<EditText
style="#style/CustomText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello, World!" />

Related

Hint and InputType on Included EditText

I have a custom EditText declared in an XML file and I'm including it like so:
<include layout="#layout/my_edit_text"
android:id="#+id/passwordField"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/passwordHint"
android:inputType="textPassword" />
and here is my_edit_text.xml:
<?xml version="1.0" encoding="utf-8"?>
<EditText xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="0dp"
android:layout_height="0dp"
android:textColor="#color/gray"
android:textSize="#dimen/editTextFontSize"
android:padding="#dimen/editTextPadding"
android:background="#drawable/edit_text_background"
android:ellipsize="end" />
However, I can't set the hint or inputType this way, for some reason. If I set it in my_edit_text.xml, it works fine, but I would like to be able to set each reference individually.
The reason that I have the custom EditText is to avoid having to rewrite all of the common values in every one of my EditTexts.
Do I have to do something similar to what this person has? If I do, will I need to actually build a .java subclass and extract the attributes that way? That just seems excessive.
The reason that I have the custom EditText is to avoid having to rewrite all of the common values in every one of my EditTexts.
Step #1: Delete my_edit_text.xml.
Step #2: Delete all references to my_edit_text.xml.
Step #3: Define a style resource (e.g., in res/values/styles.xml) akin to:
<style name="rileyText">
<item name="android:textColor">#color/gray</item>
<item name="android:textSize">#dimen/editTextFontSize</item>
<item name="android:padding">#dimen/editTextPadding</item>
<item name="android:background">#drawable/edit_text_background</item>
<item name="android:ellipsize">end</item>
</style>
Step #4: Add style="#style/rileyText" to all EditText widgets that you want to have those particular attributes applied to.

Android: keep blue background after ListView selection

I have a ListView, and it works great on a phone. Now I am making a tablet UI, with the ListView on the left and details on the right.
When I touch an item, it flashes blue as long as it is pressed. I want to keep that blue color until another item is selected, just like the Gmail app on the Nexus 7.
What is the cleanest way to achieve that? I'd rather avoid setting backgrounds manually, I assume there is a way to mark an element as the "active" one and theme it accordingly.
What is the cleanest way to achieve that?
What you are looking for is known as the "activated" state. To make this work:
Step #1: In res/values-v11/, have a style resource that implements activated. For example, for a new project that has the AppTheme declaration defined there, go with something like:
<resources>
<style name="AppTheme" parent="android:Theme.Holo.Light"></style>
<style name="activated" parent="AppTheme">
<item name="android:background">?android:attr/activatedBackgroundIndicator</item>
</style>
</resources>
Step #2: Define the same style in res/values/ for any older devices, just as a stub style resource, so references to it continue to work:
<resources>
<style name="AppTheme" parent="android:Theme.Light"/>
<style name="activated" parent="AppTheme"/>
</resources>
Step #3: In your layout XML resource for the row in the ListView, add style="#style/activated" to the list of attributes of the root element
Step #4: Set the ListView to be a single-choice list, such as the following line in a ListFragment:
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
You can see this in action in this sample project, this sample project, and this sample project. For more background on those first two samples, see this SO question: Complete Working Sample of the Gmail Three-Fragment Animation Scenario?
Using
android.R.layout.simple_list_item_activated_1
instead of
R.layout.simple_list_item_checkable_1.
Just for somebody checking someday.
after days of search and pulling my hair i just found out that activatedBackgroundIndicator is also available in ActionBarSherlock styling system. Most of the devs which develop backwards compatible apps, use ActionBarSherlock,so using ActionBarSherlock is a good option for most cases. So instead of using android:background="?android:attr/activatedBackgroundIndicator" which will give errors in android versions prior to 11, just use: android:background="?activatedBackgroundIndicator"
here is the example row layout xml code:
<?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="wrap_content"
//note the activatedBackgroundIndicator
android:background="?activatedBackgroundIndicator"
android:minHeight="?android:attr/listPreferredItemHeight"
android:paddingBottom="2dip"
android:paddingTop="2dip" >
<TextView
android:id="#+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:minHeight="?android:attr/listPreferredItemHeight"
android:paddingLeft="6dip"
android:paddingRight="6dip"
android:textSize="15sp" />
<TextView
android:id="#+id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:minHeight="?android:attr/listPreferredItemHeight"
android:paddingRight="5dip"
android:textSize="20dip" />
</LinearLayout>

How to style second level list of ExpandableListView?

How to change style of second level list of ExpandableListView? For example, add background color or header\footer view.
Note, that I don't need to set background to each child. I need to set style for a whole second level.
Here is an example of what I'm trying to achieve (brown layout - is second level list):
As I said, I don't need to apply style for each item individually. Because I have a repeatable image at background (not just color). I know how apply styles and how to set it to each child view, but this is not what I can use to achieve such background.
EDIT
What I'm trying to achieve:
add shadow at the top of "At the cafe". It can be done easily with ListView, but how to get ListView in such case? Is there any ListView at all?
set repeatable image as a background of second level list (not for each child view individually).
One way this can be achieved is with the following.
Create a style xml in your res/values/ directory.
Now define your style however you want it. When used this way it will change all the Views where the style is applied to this particular style.
Here is my example i tested with:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="backgroundTest" parent="#android:style/TextAppearance.Medium">
<item name="android:background">#00FF00</item>
</style>
</resources>
Now add the style to your top level layout in the xml that defines the children for your ExpandableListView. For example, here is my child (note the style in my LinearLayout):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/backgroundTest"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/rightSideTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="25dp"
android:paddingLeft="50dp"
android:paddingTop="25dp" />
</LinearLayout>
This should change the color of all your children to green, i believe. You can change the style to whatever you want. There is some great documentation that i linked that should help you out.

applying themes to my android app dynamically

I have three buttons to change themes. On clicking each button my app theme must change dynamically. How to do it programmatically.
To set the theme dynamically at runtime, call setTheme() in your activity's onCreate() method, before calling setContentView(). To change the theme, you simply need to restart your activity.
Here is a nice tutorial on how dynamically apply themes.
and this one too.
Please Visit this link for it.
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#00FF00"
android:typeface="monospace"
android:text="#string/hello" />
<TextView
style="#style/CodeFont"
android:text="#string/hello" />
By defining an xml theme file:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="CodeFont" parent="#android:style/TextAppearance.Medium">
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textColor">#00FF00</item>
<item name="android:typeface">monospace</item>
</style>
</resources>
You can also apply styles to all activities of an application:
<application android:theme="#style/CustomTheme">
Or just one activity:
<activity android:theme="#android:style/Theme.Dialog">
Sorry but you can't change styles programmatically.
how to set the Style Attribute Programmatically in Android?
There are certainly other methods to achieve this desired behavior however. You could set onclick listeners for each button, and programmatically change text size, color, background etc of your various view elements
you can use a particular theme for a given xml file.
in graphical layout you can CHANGE the theme of the layout using editing config.
use onclick event to go to next layout and here your theme will be different from the first one.
Vimalatha, to change your background when you click a button just add this code to the onClick function of your button.
myLinearLayout.setBackgroundColor(Color.BLUE);
Assuming that myLinearLayout is your LinearLayout name...

Android access attribute reference

In the Android resources xml to reference the value of an attribute for a theme you use the question-mark (?) instead of at (#). Such as ListViewCustomStyle below:
<ListView
android:id="#+id/MainScreenListView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="?ListViewCustomStyle"/>
How can I use the value of the ListViewCustomStyle in code? If I try it the normal way i.e.
com.myapp.R.attr.ListViewCustomStyle
Then the code crashes. Is there a special way to access this since it is a reference to an item and not an actual item?
It might just be crashing because you wrote ListRowCustomStyle there, and ListViewCustomStyle in your xml.
The way I do this is to have the tag style="#style/my_button" for example (with no android: preceding it). Then you can define your style in the values/styles.xml file, e.g.
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="my_button" parent="#android:style/Widget.Button">
<item name="android:gravity">center_vertical|center_horizontal</item>
<item name="android:textColor">#FFFFFFFF</item>
...
</style>
</resources>
You can access the style in code by using the id R.style.my_button
I believe in the xml you wanted to write
style="#style/ListViewCustomStyle"
Anyway, how to use it in code?
Last time I check, it was impossible :(
I did it with a trick:
create a layout file as the example that follows:
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="#style/MyCustomStyle"/>
when you want to add an object with your custom style in code, you have to inflate it, using this layout you just created:
:
LayoutInflater inflater = LayoutInflater.from(this); // this = activity or context
Button button = (Button) inflater.inflate(R.layout.myButtonWithMyStyle, null); //use the same layout file as above
button.setText("It works!");
myView.addView(button);
This is considerably slower than creating a Button in code. It may be a problem if you create hundreads of Views at the same time using this method. Less than that I think you can handle it.

Categories

Resources