Android layout as button with selectable functionality - android

I'm trying to create a button-like component, with a left-aligned ImageView and then 2 TextViews to the right of the ImageView, stacked one above the other and formatted differently, like the following example:.
__________________________
| |
| |-----| Bold Main Text |
| |Image| |
| |-----| Small Sub Text |
|__________________________|
I also want the ImageView to change depending on the click state of the outer container, much like a standard button would do with a selectable resource associated with it. So that when I click anywhere in the outer box the image selectable state is changed.
I know I can use a Button, setting the 'drawableLeft' property to create a single line of text associated with an Image as a button, but it seems I can only have a single item of text using this strategy.
Has anyone implemented any UI components like this in the past?
Thanks!

You can add android:duplicateParentState="true" to the ImageView widget. Also you need to make the ImageView's parent clickable and focusable.
The RelativeLayout in the following code will act as a Button:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout:height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true">
<ImageView
android:id="#+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:duplicateParentState="true"
android:src="#drawable/icon" />
<TextView
android:id="#+id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/image"
android:layout_alignTop="#+id/image"
android:layout_alignWithParentIfMissing="true"
android:duplicateParentState="true" />
<TextView
android:id="#+id/text2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/image"
android:layout_below="#+id/text1"
android:layout_alignWithParentIfMissing="true"
android:duplicateParentState="true" />
</RelativeLayout>
</LinearLayout>

Related

How to dynamically set button in a tabular form

I am making the layout for my activity and got puzzelled , I am thinking about making the flexible layout in which my views get width and height according to screen. Please read the case below
What I want:
This is the trickiest and hardest part for me.
I need to put the 37 buttons on the screen , such that the each row
gets the 3 button and then shift to new row. nevertheless the last row get the single button or two buttons. Well in the case of 3
button in each row yields only single button in last row but that's
okay
Each button in each row should have different id , having different
picture on background and opening different activity with different
intent extras.
Buttons in row must have same sizes so that it should look good.
So these three points are giving me tough time. Also the 2nd point in these point is much much more important.
Please tell me How Can I achieve this I have read about grid layout , Grid view , list view , table layout and also I have used them many time. but I do not know how to use them for this specific purpose.
Note: The buttons in the row should get the same width and height according to screen and the layout should get fit on all devices so we should avoid hard coded values.
Simply use grid view. Set Max column to 3 and
Use a custom adapter extending Base adapter to set backgrounds and return different ids on item click listener.
Set layout param for inflated item view dynamically using screen size.
I think you should see these links , link 1 and link2. The gridview is best option is for you as these layouts adjust the size and you can easily Handle them in their adapter.
Use a Linear layout instead..with Nested concept.that is like
<LinearLayout>
<LinearLayout>
.
.
And So on..
.
.
.
</LinearLayout>
</LinearLayout>
For example
----Outer (Horizontal) layout-----
| |
| ---Inner (Vertical) layout- |
| | [Textview] | |
| | [Button] | |
| | [Button] | |
| | [Button] | |
| --------------------------- |
----------------------------------
Also try the example below
<LinearLayout android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout android:layout_height="wrap_content"
android:layout_width="match_parent">
<TextView android:text="One,One"
android:layout_height="wrap_content"
android:layout_width="wrap_content" />
<TextView android:text="One,Two"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_weight="1" />
<TextView android:text="One,Three"
android:layout_height="wrap_content"
android:layout_width="wrap_content" />
<TextView android:text="One,Four"
android:layout_height="wrap_content"
android:layout_width="wrap_content" />
</LinearLayout>
<LinearLayout android:layout_height="wrap_content"
android:layout_width="match_parent">
<TextView android:text="Two,One"
android:layout_height="wrap_content"
android:layout_width="wrap_content" />
<TextView android:text="Two,Two"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_weight="1" />
<TextView android:text="Two,Three"
android:layout_height="wrap_content"
android:layout_width="wrap_content" />
<TextView android:text="Two,Four"
android:layout_height="wrap_content"
android:layout_width="wrap_content" />
</LinearLayout>
<LinearLayout android:layout_height="wrap_content"
android:layout_width="match_parent">
<TextView android:text="Three,One"
android:layout_height="wrap_content"
android:layout_width="wrap_content" />
<TextView android:text="Three,Two"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_weight="1" />
<TextView android:text="Three,Three"
android:layout_height="wrap_content"
android:layout_width="wrap_content" />
<TextView android:text="Three,Four"
android:layout_height="wrap_content"
android:layout_width="wrap_content" />
</LinearLayout>
<LinearLayout android:layout_height="wrap_content"
android:layout_width="match_parent">
<TextView android:text="Four,One"
android:layout_height="wrap_content"
android:layout_width="wrap_content" />
<TextView android:text="Four,Two"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_weight="1" />
<TextView android:text="Four,Three"
android:layout_height="wrap_content"
android:layout_width="wrap_content" />
<TextView android:text="Four,Four"
android:layout_height="wrap_content"
android:layout_width="wrap_content" />
</LinearLayout>
</LinearLayout>
Output
Reference Links:
Nested Linear Layout,
Nested Example
Update 1
As you said, 37 buttons have to implement on the application with different id,intent extras etc.it is simple job i think. set each buttons with different id and write a onClickListener for the buttons.Use a switch/If case t\o distinguish each buttons.
Example:
public void buttonOnClick(View view)
{
switch(view.getId())
{
case R.id.button1:
// Code for button 1 click
break;
case R.id.button2:
// Code for button 2 click
break;
case R.id.button3:
// Code for button 3 click
break;
}
}
Refer this link for more info:
OnClickevent for buttons
Thanks

Relativelayout - how to use nested RelaitveLayout-blocks

I am trying to switch my app-layout from a LinearLayout to RelativeLayout. For me its important to keep a good code-structure andI I consider it more readable if I have a parent RelativeLayyout for the whole screen and then have nested Relative Layouts thats holding the Views.
for instance, I have a RelativeLayout that holds a Spinner, then under that I have a block that shows textviews and imageViews associated with date, and under that I have another Relativelayout that holds views asscociated with time.
This is how I organized the layout when using a LinearLayout. I want the same organization with Relativelayout. see below
|-----------------------------|
| (SPINNER) textview |
|-----------------------------|
| (DATE) textView imageview |
|-----------------------------|
| (TIME) textview imageview |
|-----------------------------|
that is - the child is organized in a sub-RelativeLayout (nested). And I thought I could just put the individual RealtiveLayouts beneath each other by just use an anchor-id
and then use
android:layout_below="#+id/relativeLayoutDate"
that is the third block - time should be put under the the date-block
But obviously I am doing something wrong because all views is in the uppermost corner right now in the screen.
Here I post some part of the xml-layout file. Would be glad i someone knew whats wrong and how to fix it.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!-- spinner -->
<RelativeLayout
android:id="#+id/relativeLayoutSpinner"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Spinner
android:id="#+id/planets_spinner"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/spinnerrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/spinnerrow"/>
</RelativeLayout>
<!-- date -->
<RelativeLayout
android:id="#+id/relativeLayoutDate"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/relativeLayoutSpinner">
<TextView
android:id="#+id/textLabel_setDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="set date: "
android:layout_marginTop="25dp"/>
<ImageView
android:id="#+id/dateImg"
android:layout_width="60dp"
android:layout_height="64dp"
android:layout_marginLeft="8dp"
android:layout_toRightOf="#+id/textLabel_setDate"
android:src="#drawable/date"/>
<TextView
android:id="#+id/setDate_txtView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="25dp"
android:layout_marginLeft="8dp"
android:layout_toRightOf="#+id/dateImg"
android:layout_centerInParent="true" />
<ImageView
android:id="#+id/uncheckedImg"
android:layout_width="25dp"
android:layout_height="40dp"
android:layout_marginLeft="100dp"
android:layout_gravity="right"
android:layout_toRightOf="#+id/setDate_txtView"
android:src="#drawable/unchecked"/>
</RelativeLayout>
<!-- time -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/relativeLayoutDate"
>
<TextView
android:id="#+id/textLabel_setTime"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginTop="20dp"
android:text="set time: " />
<ImageView
android:id="#+id/timeImg"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_marginLeft="8dp"
android:layout_toRightOf="#+id/textLabel_setTime"
android:src="#drawable/time"/>
<TextView
android:id="#+id/setTime_txtView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginLeft="8dp"
android:layout_toRightOf="#+id/timeImg"
android:layout_centerInParent="true" />
</RelativeLayout>
In the code your using match_parent for all the RelativeLayout's, don't use match_parent for all sub-layout's. It will hide the previous one's.
android:layout_width="match_parent"
android:layout_height="match_parent"
make it only for parent and remaining should be wrap_content
You should not create 3 relative layouts but just ONE and then use below & rightof on all views to display them properly, since this looks like a form however i would strongly suggest using GridLayout which is meant exactly for that, see documentation here:
http://developer.android.com/reference/android/widget/GridLayout.html
I might be wrong and yet it appears to me that one closing tag missing.
You did open/created 4 Relative Layouts and yet I only could find 3 that closed.
1) <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<!-- spinner -->
2)<RelativeLayout
2)</RelativeLayout>
<!-- date -->
3)<RelativeLayout
3)</RelativeLayout>
<!-- time -->
4)<RelativeLayout
4)</RelativeLayout>

RelativeLayout: Can't assign a view above a referenced view if margin is involved

I was trying to put a TextView dependent above the other TextView anchor inside a RelativeLayout, but I can't manage to make the dependent get displayed.
Situation:
The anchor would be aligned with the parent's top + some marginTop to make it more to the center of the parent (RelativeLayout), and the dependent will be aligned to be above of this anchor.
This doesn't work; when I assigned it to be above the anchor it seems that android assumes the top of the anchor is the parent's top and draws the dependent outside the screen (above it).
This should not be the case since I use margin instead of padding so the area between the top of the RelativeLayout and the anchor shouldn't be the part of the anchor itself (I checked the size with hierarchy viewer). Or maybe I get it wrong? :S
This is the simple layout code:
<?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"
>
<TextView android:id="#+id/anchor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginTop="100px"
android:text="Anchor point."
/>
<TextView android:id="#+id/dependent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#id/anchor"
android:text="Dependent."
/>
</RelativeLayout>
Desired:
-------------
| |
|dependent |
|anchor |
| |
-------------
What happened:
dependent (out of screen display)
-------------
| |
| |
|anchor |
| |
-------------
Hope:
Could someone help me here? Or maybe help pointing out if I made a mistake. I need to use the RelativeLayout in my real implementation (above is just an example).
Thanks in advance.
I made an invisible button to align from - is this what you're looking for? If you change the margin or any location parameter of the anchorbutton it will change the location of the dependants.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button android:id="#+id/anchorbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="100dp"
android:visibility="invisible"
/>
<TextView android:id="#+id/anchor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/anchorbutton"
android:layout_alignLeft="#id/anchorbutton"
android:layout_margin="10dp"
android:text="Off Anchor button"
/>
<TextView android:id="#+id/dependent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#id/anchorbutton"
android:layout_below="#id/anchor"
android:layout_margin="50dp"
android:text="Dependent."
Can I ask why you don't make the anchor at the uppermost corner (top or bottom - doesn't matter) and then build your view from that? That's what I do and that's below: Sorry - I can't post pics yet.
<?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">
<TextView android:id="#+id/anchor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginTop="100dp"
android:text="Anchor point."
/>
<TextView android:id="#+id/dependent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/anchor"
android:layout_alignLeft="#id/anchor"
android:text="Dependent."
/>
</RelativeLayout>
Alternatively, if you really want to keep things as they are, just change the alignment of dependent to android:layout_alignParentTop="true". You can have margin here as well to affect it's placement. Here's the code and pic.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView android:id="#+id/anchor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginTop="100dp"
android:text="Anchor point."
/>
<TextView android:id="#+id/dependent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginTop="150dp"
android:text="Dependent."
/>
</RelativeLayout>

Android layout space-filling problem

I'm having real difficulty coming up with a layout which works. I have a view which fills the width of the screen. It contains three sub-views:
Some text
A number in parentheses after the main text
A button
The button is right-aligned, and the text items are left-aligned one after the other, as shown:
| Some heading text (n) [button] |
The problem is controlling what happens when the text is too long. I want it like this, so that the number is always visible just to the right of the main text. The main text should be truncated if needed so the other two views remain visible.
| Some very very long headin... (n) [button] |
The closest I've got which succesfully truncates the main text results in the (n) always being right-aligned next to the button even when the main text is short enough to fit. That's not what I want.
How would you approach this?
I'm not posting any of my current XML yet, lest it prejudice anyone's suggestions.
I do not believe there's any xml layout for that. My guess is that you will need to extend TextView and measure the text length inside onDraw(...), adjusting the text accordingly through some iteration (i.e., removing one character at a time until the text fits the canvas)
I just found another question that is quite similar to yours: Ellipsize only a section in a TextView . No other answer than ellipsize in the middle.
Another thoughts:
I'm wondering if it would work to have one textview with the main text (ellipsize left, wrap_content) and another with the number in the parenthesis (wrap_content), both inside an horizontal linear layout. That layout would be inside a relative layout and layout_toLeftOf the button, which would be wrap_content, layout_alignParentRight.
Does it make any sense? I don't have Eclipse now to test it myself. Not sure if the (n) textview would be lost behind the button or not with a long text.
Alternatively (and less interesting), you can setup one single relative layout with the two textviews all layout_toRightOf and the button aligned to the right (layout_alignParentRight) and set the max witdth ot the first textview (android:maxWidth). You would need to set up different layouts for different screens, though.
An example with a fixed max width that will work as required:
<?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"
>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="click me"
android:id="#+id/bt1"
android:layout_alignParentRight="true"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="short text"
android:lines="1"
android:ellipsize="end"
android:id="#+id/t1"
android:layout_alignParentLeft="true"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="(n)"
android:lines="1"
android:id="#+id/n1"
android:layout_toRightOf="#id/t1"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="click me"
android:id="#+id/bt2"
android:layout_below="#id/bt1"
android:layout_alignParentRight="true"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="very long text that will not fit in any layout, regardless of the size of the screen"
android:lines="1"
android:ellipsize="end"
android:id="#+id/t2"
android:layout_below="#id/bt1"
android:layout_alignParentLeft="true"
android:maxWidth="220dp"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="(n)"
android:lines="1"
android:id="#+id/n2"
android:layout_below="#id/bt1"
android:layout_toRightOf="#id/t2"
/>
</RelativeLayout>
Try a linearlayout, set the weight of the text view as 1,, and set ellipsis as TruncateAt.MIDDLE. Check this layout
<?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="wrap_content">
<TextView android:id="#+id/text" android:layout_width="0dp"
android:layout_height="wrap_content" android:lines="1"
android:ellipsize="middle" android:gravity="left"
android:layout_weight="1" />
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
The key is the ordering of the items as this is the order they are measured, in order to ensure your button and (n) text get enough space in the overall layout:
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
>
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
/>
<TextView
android:id="#+id/middle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="left"
android:layout_toLeftOf="#id/button"
android:text="(n)"
/>
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="#id/middle"
android:layout_alignParentLeft="true"
android:gravity="left"
android:ellipsize="end"
android:text="Some really long to text to make this flow over"
android:lines="1"
android:maxLines="1"
/>
</RelativeLayout>

Android: On text overflow, go to new line?

I've got the following Layout...
<LinearLayout android:id="#+id/linearLayout1" android:layout_width="match_parent" android:orientation="horizontal" android:layout_height="wrap_content">
<ImageView android:id="#+id/Pic" android:src="#drawable/icon" android:layout_width="25dip" android:layout_height="25dip"></ImageView>
<LinearLayout android:id="#+id/linearLayout2" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content">
<TextView android:textColor="#5379E2" android:text="Item" android:id="#+id/Title" android:layout_width="wrap_content" android:layout_height="match_parent"></TextView>
<TextView android:text="" android:textColor="#000000" android:id="#+id/Description" android:layout_width="wrap_content" android:layout_height="match_parent"></TextView>
<TextView android:text="" android:textColor="#000000" android:id="#+id/url" android:layout_width="wrap_content" android:layout_height="match_parent"></TextView>
</LinearLayout>
</LinearLayout>
Whenever the text gets too large for the single line it's on it overflows like so..
This is the first line and when it gets too big it does
t
h
i
s
But, what I'd like it to do is this..
This is the first line and when it gets too big it should
do this.
How would I achieve this?
EDIT
So It's appears this is happening because each of the three Textviews are taking up space like so..
|------|-----|-----|
| | | |
|______|_____|_____|
So, when it overflows it goes down to it's respective textline. The problem is this isn't what I want. I need the 3 textviews appears to compose of one sentence. I haven't just used one textview because I want to colour each textview differently.
Have you tried this setting for your textview?
android:singleLine="false"

Categories

Resources