The Problem: How to uniquely identify elements which are inside android Compound View?
Background:
In my application I used Compound View. Because It has two TextFields, one image and one seek bar in each row. The layout is working fine.
So in the layout there are two separate seek bars. I need to get the value of them in my activity.
I can identify each row separately because they have id. But the items inside the row repeat in each row.
My problem is
how can I identify each seek bar uniquely?
row_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android" >
<RelativeLayout
android:id="#+id/colunm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="40sp" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="6dip"
android:layout_marginRight="6dip"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="?android:attr/textAppearanceSmall" />
<SeekBar
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
</merge>
screen_layout.xml
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.example.test.view.Compound
android:id="#+id/vol_Row1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
custom:column_summary="TEST SUMMARY I"
custom:column_title="Test TITLE 1"
custom:image_Icon="#drawable/ic_action1" />
<com.example.test.view.Compound
android:id="#+id/vol_Row2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
custom:column_summary="TEST SUMMARY 2"
custom:column_title="Test TITLE 2"
custom:image_Icon="#drawable/ic_action2" />
</LinearLayout>
row_layout class
public Compound(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a=context.obtainStyledAttributes(attrs,R.styleable.Options, 0, 0);
String titleText=a.getString(R.styleable.Options_title);
String summaryText=a.getString(R.styleable.Options_summary);
int icon=a.getInt(R.styleable.Options_image_Icon,0);
a.recycle();
LayoutInflater inflater=(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.row_layout,this,true);
imageView=getChildAt(0);
imageView.setImageResource(icon);
title=getChildAt(1)
title.setText(titleText);
summary=getChildAt(2)
summary.setText(summaryText);
}
}
First, add an ID to the seekbar in your XML layout file.
<SeekBar
android:id="#+id/seek"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
Second, in your code, use findViewById on the instance of the Compound view of which you want to obtain the reference to it's seek bar:
Coumpund c1 = (Compound)findViewById(R.id.vol_Row1);
Coumpund c2 = (Compound)findViewById(R.id.vol_Row2);
SeekBar sb1 = (SeekBar)c1.findViewById(seek); // Gives you the SeekBar of c1
SeekBar sb2 = (SeekBar)c2.findViewById(seek); // Gives you the SeekBar of c2
I did it in this way. In compound view I gave unique ids to each element. Then in test code I could access them uniquely like this,
private View inflaterView;
LayoutInflater i=(LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflaterView=i.inflate(R.layout.screen_layout, null);
seekBar=(SeekBar) inflaterView.findViewById(R.id.vol_Row1).findViewById(R.id.seekbar);
Related
This is the item I'm inflating:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#drawable/background_border"
android:padding="10dp"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Account name"
android:textSize="25sp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Balance: £61.43"
android:textSize="25sp"
android:paddingTop="40dp"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_keyboard_arrow_right_black_24dp"
android:layout_alignParentEnd="true"
android:layout_centerInParent="true"/>
</RelativeLayout>
And I'm inflating it using the following code:
LinearLayout parent = (LinearLayout) findViewById(R.id.linearL);
view = getLayoutInflater().inflate(R.layout.menu_item, parent,false);
parent.addView(view);
Say if I inflated the following item three times, to create three menu items - how would I reference each item individually?
For example, if I wanted to change the text of the Account name in the first item of the menu, how would I reference that it's in the first item of the menu, instead of the second or third?
Say if I inflated the following item three times, to create three menu
items - how would I reference each item individually?
Use parent.getChildCount() and parent.getChildAt() for accessing Views from any R.layout.menu_item layout like:
Add layout multiple times:
//First time
parent.addView(view);
//Second time
parent.addView(view);
Get first added R.layout.menu_item layout view:
View firstView=parent.getChildAt(0);
In same way get other child View of parent layout.
Access child Views from firstView using :
View id if added in xml:
TextView textView=(TextView)firstView.findViewById(R.id.textViewID);
or using getChildAt method:
TextView textView=(TextView)firstView.getChildAt(0);
Access other views in same way.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#drawable/background_border"
android:padding="10dp"
>
<TextView
android:id="#+id/account_name_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Account name"
android:textSize="25sp"/>
<TextView
android:id="#+id/balance_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Balance: £61.43"
android:textSize="25sp"
android:paddingTop="40dp"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_keyboard_arrow_right_black_24dp"
android:layout_alignParentEnd="true"
android:layout_centerInParent="true"/>
</RelativeLayout>
And in code you will have some thing like
TextView textview = (TextView)relativeLayoutFromXml.findById(R.id.balance_text_view);
textview.setText("sadsasa ");
If your layout is inside activity xml you should access the textview like this:
TextView textview = (TextView) findViewById(R.id.balance_text_view);
textview.setText("sadsasa ");
In my application, I have a layout list_item.xml with 3 textviews which are filled from an array and I want to inflate this 3 textviews alone in another layout. The layout in which I want to inflate is a separate xml file layout_result.xml which has a single button and android search widget.
layout file for list_item.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minWidth="25px"
android:minHeight="25px"
android:background="#F0F8FF"
android:orientation="horizontal"
android:layout_weight="1">
<TextView
android:id="#+id/ID"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/ProductName"
android:layout_alignBottom="#+id/ProductName"
android:layout_alignParentLeft="true"
android:text="New Text" />
<TextView
android:id="#+id/Status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginRight="17dp"
android:layout_marginTop="42dp"
android:text="New Text" />
<TextView
android:id="#+id/Name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/Status"
android:layout_alignBottom="#+id/Status"
android:layout_centerHorizontal="true"
android:text="New Text" />
</RelativeLayout>
Layout for list_resut.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minWidth="25px"
android:minHeight="25px"
android:background="#F0F8FF"
android:orientation="horizontal"
android:layout_weight="1">
<SearchView
android:id="#+id/searchView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="118dp"
android:layout_marginTop="16dp" >
</SearchView>
<Button
android:id="#+id/search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignTop="#+id/searchView1"
android:layout_marginLeft="22dp"
android:text="Button" />
</RelativeLayout>
Problem I faced when I tried to include search widget and button within list_item.xml and inflating them was that the search widget and button were being inserted in each of the 3 textview element.
So I created this separate layout list_result.xml which holds only the search widget and the button.
Question, is there anyway where I can place this list_item.xml with the textview results within list_result.xml to over come this error?
My layout inflater for list_item looks like this,
public View getView(int i, View view, ViewGroup viewGroup) {
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View itemView = inflater.inflate(R.layout.list_item, viewGroup, false);
TextView txtName = (TextView) itemView.findViewById(R.id.Name);
TextView txtID= (TextView) itemView.findViewById(R.id.ID);
TextView txtStatus = (TextView) itemView.findViewById(R.id.Status);
txtName.setText(list.get(i).getProductName());
txtID.setText(list.get(i).getProductID());
txtStatus.setText(list.get(i).getStatus());
return itemView;
}
}
You should be able to just create a single layout XML. Not sure how you did it previously but you could do something like this:
<RelativeLayout>
<RelativeLayout>
<TextView/>
<TextView/>
<TextView/>
</RelativeLayout/>
<SearchView/>
<Button/>
</RelativeView>
If you want to keep the XML separate and then combine them at runtime, you still need a "container" for the inflated text views. You could use a FrameLayout as the container. Something like this for example:
results.xml:
<RelativeLayout>
<FrameLayout/>
<SearchView/>
<Button/>
</RelativeLayout>
items.xml
<RelativeLayout>
<TextView/>
<TextView/>
<TextView/>
</RelativeView/>
And then you can insert the textviews into the other layout like this:
ViewGroup container = (ViewGroup) findViewById(R.id.FrameLayoutId);
container.addChild(yourInflaterItemsView);
Hope this helps
Having trouble getting layout inflater to work - wondering if someone get shed some light on why the text view is not working..
this is main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_horizontal"
android:background="#A9BCF5"
android:orientation="vertical"
tools:context=".MainActivity"
android:weightSum="1">
<ImageView
android:layout_width="639dp"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:id="#+id/imageView"
android:background="#drawable/retreatgoddess"
android:scaleType="centerCrop"
android:clickable="true"
android:cropToPadding="false"
android:longClickable="false"
android:layout_weight="0.80" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/affirmation"
android:layout_weight="0.23"
android:textAlignment="center"
android:textColor="#1728ff"
android:textStyle="normal"
android:typeface="sans"/>
</LinearLayout>
this is the method
public void fillTextView(Context context, int layoutId, int resId, String text)
{
View view= LayoutInflater.from(context).inflate(layoutId, null);
TextView textElement = (TextView) view.findViewById(resId);
textElement.setText(text);
}
i am calling it via
fillTextView(context, R.layout.main, R.id.affirmation, "i love you");
i am getting the background but no text
As you're using layout weight, you should set android:layout_height to 0px on both imageView and affirmation. Then the layout will be calculated properly.
Also, the total weight in your case is 1.03, yet you set the sum to 1.0. Change the sum or one of the layout weights.
Here is my Prent layout (main.xml)
<!-- ============================================================ -->
<!-- All Employees are added here (added and More then one) -->
<!-- ============================================================ -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/myLayout"
android:orientation="vertical"
android:layout_gravity="center_vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#00000000">
<!-- ++++++++ here extra layout is added programmatically -->
</LinearLayout>
Here is my another layout file that I want as child, say child.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linearLayout2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:gravity="center_vertical"
android:orientation="horizontal" >
<Button
android:id="#+id/btn_left"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:singleLine="false"
android:maxLines="2"
android:text="hello"/>
<TextView
android:id="#+id/list_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:gravity="center_horizontal"
android:text="Photos"
android:textAppearance="?android:attr/textAppearanceLarge" />
<Button
android:id="#+id/btn_right"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="Save" />
</LinearLayout>
Now in my Main activity I am calling the main.xml and based on the for loop condition I want to add the layout of the child.xml and every time I want to set the different value of the TextView of child.xml
So how it is Possible?
I have done like this:
private void doCalculationForMultipleEmployee() {
singleEmployee.setVisibility(View.GONE);
for (int i = 0; i<=tempEmployerList.size()-1; i++) {
View repeatedLayout = LayoutInflater.from(getApplicationContext()).inflate(R.layout.test);
((TextView)repeatedLayout.findViewById(R.id.list_title)).setText("Employee"+i);
// customize repeatedLayout with other data
myLinearLayout.addChild(repeatedLayout);
}
}
But after doing that I got syntax error at .inflate and at .addChild
So where have I gone wrong? Please help me by some code to add it by for loop.
Just create a loop like below:
LinearLayout parent=findViewById(R.id.myLayout);
for(int i=0;i<list.size();i++)
{
LinearLayout llItem=(LinearLayout)LayoutInflater.createFromSource(R.layout.child, null);
TextView txt= (TextView)llItem.findViewById(R.id.title);
txt.setText(list.get(i));
parent.add(llItem);
}
Inflate the view then add to the parent
LinearLayout parent = (LinearLayout)findViewById(R.id.myLayout);
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
Layout child = inflater.inflate(R.layout.myLayout2, null);
TextView title = (TextView)child.findViewById(R.id.list_title);
parent.addView(child);
Repeat as many times as necessary or use a loop
If i understood your question correctly you need to display button, textview and button side by side in your layout.
If you want this you just take listview and use custom adapter, with this you can display button, text and button side by side
I'm writing a preference screen in in xml for my Android application. My issue is that some of the titles of the preferences are too long and will not wrap the page. Consider my example:
<CheckBoxPreference
android:title="Language Detection (BETA)"
android:defaultValue="false"
android:summary="Automatically decide which language to use"
android:key="lan_det_pref"
android:textSize="15px"
android:lines="4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
Maybe I'm missing something but I have tried using number of other properties with no positive results. I have tried android:singleLine, android:lines, etc., and none of these seem to effect the title of the preference. Also is there a way to scale down the size of a CheckBox title?
Any help would be greatly appreciated.
Thanks :)
A CheckBoxPreference is not derived from View, so the usual view attributes don't apply.
Instead, a CheckBoxPreference is bound to a view, which has a predefined layout.
You can derive a class from CheckBoxPreference and override onBindView. In your class' onBindView, find the CheckBox view and adjust its view attributes to your liking.
class MyCBPref extends CheckBoxPreference{
public MyCBPref( Context context, AttributeSet attrs){
super(context, attrs);
}
protected void onBindView( View view){
super.onBindView(view);
makeMultiline(view);
}
protected void makeMultiline( View view)
{
if ( view instanceof ViewGroup){
ViewGroup grp=(ViewGroup)view;
for ( int index = 0; index < grp.getChildCount(); index++)
{
makeMultiline(grp.getChildAt(index));
}
} else if (view instanceof TextView){
TextView t = (TextView)view;
t.setSingleLine(false);
t.setEllipsize(null);
}
}
}
Then in your layout, reference your class instead of CheckBoxPreference:
<com.mycorp.packagename.MyCBPref android:title="..." ... />
You could customize you checkbox like this:
MyPreference.xml
<CheckBoxPreference android:key="testcheckbox"
android:title="Checkbox Title"
android:summary="Checkbox Summary..."
android:layout="#layout/custom_checkbox_preference_layout">
</CheckBoxPreference>
and custom_checkbox_preference_layout.xml
<?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"
android:minHeight="?android:attr/listPreferredItemHeight"
android:gravity="center_vertical"
android:paddingLeft="16dip"
android:paddingRight="?android:attr/scrollbarSize">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:id="#+android:id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
/>
</LinearLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="6dip"
android:layout_marginTop="6dip"
android:layout_marginBottom="6dip"
android:layout_weight="1">
<TextView android:id="#+android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="false"
android:textAppearance="?android:attr/textAppearanceMedium"
android:ellipsize="marquee"
android:fadingEdge="horizontal" />
<TextView android:id="#+android:id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#android:id/title"
android:layout_alignLeft="#android:id/title"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary"
android:maxLines="4" />
</RelativeLayout>
<!-- Preference should place its actual preference widget here. -->
<LinearLayout android:id="#+android:id/widget_frame"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical" />
</LinearLayout>
the point is android:singleLine="false"".
You can derive a class from CheckBoxPreference and override onBindView. In your class onBindView, find the CheckBox view and adjust its view attributes to yours.