How to access the main activity's view from a custom widget? - android

I have a custom "view" widget (CustomController) on my application's main screen.
In the widget's constructor, I can access an image in the widget's xml file with the following code:
(Note, img_cursor is an ImageView in "custom_controller.xml")
public final class CustomController extends LinearLayout{
public CustomController(Context context, AttributeSet attrs) {
super(context, attrs);
LayoutInflater layoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view_controller = layoutInflater.inflate(R.layout.custom_controller,this);
img_cursor = (ImageView) view_dpad.findViewById(R.id.img_cursor);
...
However, I want to access a TextView on the main activity's screen.
The custom controller widget is displayed on the main screen through main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linlayRoot"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.test.projectname.CustomController
android:id="#+id/dpad"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginRight="15px"
android:layout_marginLeft="15px" />
<Button
android:text="Connect"
android:id="#+id/btn_connection"
android:layout_height="wrap_content"
android:layout_width="100dp">
</Button>
<Button
android:text="Settings"
android:id="#+id/btn_settings"
android:layout_height="wrap_content"
android:layout_width="wrap_content">
</Button>
<Button
android:text="Debug x,y"
android:layout_width="wrap_content"
android:id="#+id/btn_debug_x_y"
android:layout_height="wrap_content">
</Button>
<TextView
android:id="#+id/txt_view_x"
android:layout_marginLeft="20dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="X = 0">
</TextView>
<TextView
android:id="#+id/txt_view_y"
android:layout_marginLeft="20dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Y = 0">
</TextView>
</LinearLayout>
How do I access the TextViews in main.xml from the CustomController class?
I've tried stuff like:
public final class CustomController extends LinearLayout{
public CustomController(Context context, AttributeSet attrs) {
super(context, attrs);
LayoutInflater layoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View main_controller = layoutInflater.inflate(R.layout.main,this);
textview = (TextView) view_dpad.findViewById(R.id.txt_view_x);
...
I can't seem to access the main screen's view. It doesn't like:
View main_controller = layoutInflater.inflate(R.layout.main,this);
Thanks for any help!

Related

Android I cannot inflate custom view

I create a custom view for actionbar.When i use <inclued layout=#layout/XXXXX />is ok.However ,when i use LayoutInflater to inflate the view ,it cannot inflate it .Here is my code
public class TitleLayout extends LinearLayout {
// private Button btn_back;
// private Button btn_edit;
public TitleLayout(Context context, AttributeSet attrs) {
super(context, attrs);
LayoutInflater.from(context).inflate(R.layout.view_title,this);
}
}
TitleLayout is my custom view
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/btn_back"
android:layout_gravity="center"
android:text="Back"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="#+id/text_title"
android:text="This is a title"
android:layout_gravity="center"
android:textSize="30sp"
android:gravity="center"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="#+id/btn_edit"
android:text="Edit"/>
</LinearLayout>
It is a simple view; When i use <inclued /> to inflate is ok. But use LayoutInflate will show nothing.
<!--<include-->
<!--layout="#layout/view_title"/>-->
<com.example.administrator.test.TitleLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
</com.example.administrator.test.TitleLayout>
really appreciate your help!!!
try this
public class TitleLayout extends LinearLayout {
public TitleLayout (Context context) {
super(context);
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
layoutInflater.inflate(R.layout.your_layout, this);
}
}

RelativeLayout, match parent contains unwanted padding right?

I have a custom header bar (something like actionbar).
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#drawable/bg_header">
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/ibSlider"
android:src="#drawable/ic_drawer"
android:background="#color/transparent"
android:layout_marginLeft="#dimen/side_margin"
android:contentDescription="#string/general_content_description"
android:layout_centerVertical="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="#string/header_branding"
android:id="#+id/tvAppName"
android:layout_toRightOf="#+id/ibSlider"
android:gravity="center_vertical"
android:layout_marginLeft="#dimen/side_margin"
style="#style/branding_orange"/>
<ProgressBar
android:layout_width="20dp"
android:layout_height="20dp"
android:id="#+id/pbLoading"
android:layout_alignParentRight="true"
android:indeterminate="true"
android:layout_marginRight="#dimen/side_margin"
android:layout_centerVertical="true"/>
</RelativeLayout>
When I'm adding this custom view in my activity, there is padding right that I have no idea comes from where! I have added green background to the view in order to find I'm talking about where.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<view
android:layout_width="match_parent"
android:layout_height="50dp"
android:id="#+id/headerBar"
android:background="#color/green"
class="com.kamalan.widget.HeaderBar"/>
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/headerBar"/>
</RelativeLayout>
And this is the code of my HeaderBar.
public class HeaderBar extends RelativeLayout {
private static final String TAG = "HeaderBar";
private Context mContext;
private ProgressBar progressBar;
private ImageButton ibMenuSlider;
public HeaderBar(Context context) {
super(context);
this.mContext = context;
init();
}
public HeaderBar(Context context, AttributeSet attrs) {
super(context, attrs);
this.mContext = context;
init();
}
public HeaderBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.mContext = context;
init();
}
private void init() {
LayoutInflater mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
RelativeLayout view = (RelativeLayout) mInflater.inflate(R.layout.widget_headerbar, null);
addView(view);
progressBar = (ProgressBar) view.findViewById(R.id.pbLoading);
ibMenuSlider = (ImageButton) view.findViewById(R.id.ibSlider);
}
...
}
Image 1 shows preview of class header (first xml code) and second image displays when it has been added to my activity. I have no idea that green padding comes from where! any idea would be appreciated. thanks.
Problem was the image that I was using as background of Header. Have no Idea why it works on first image but doesn't work on second one. Maybe activity is messing or Theme has bug, as Bob said in comment.
Anyways, I fixed the problem by not using image :)
For other's reference, I changed xml of header as below and I could fix the problem in this way.
<?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="#dimen/header_bar_height"
android:background="#color/gray">
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/ibSlider"
android:src="#drawable/ic_drawer"
android:background="#color/transparent"
android:layout_marginLeft="#dimen/side_margin"
android:contentDescription="#string/general_content_description"
android:layout_centerVertical="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="#string/header_branding"
android:id="#+id/tvAppName"
android:layout_toRightOf="#+id/ibSlider"
android:gravity="center_vertical"
android:layout_marginLeft="#dimen/side_margin"
style="#style/branding_orange"/>
<ProgressBar
android:layout_width="20dp"
android:layout_height="20dp"
android:id="#+id/pbLoading"
android:layout_alignParentRight="true"
android:indeterminate="true"
android:layout_marginRight="#dimen/side_margin"
android:layout_centerVertical="true"/>
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="#color/header_divider"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
I also face same problem but i get success when i try customize Actionbar.I am unable to resolve your problem due to absence of drawable and string resource so please provide zip of this one so that i can see directly .....

xml LinearLayout different behaviours

I am trying to create a custom button layout. I created an xml file "custom_button.xml" which I then inflate in the "ButtonLanguageSelection" class. In this class I added the onClickListener. I added this class to the "main_activity.xml". It behaves like it should except it won't receive any touch events. Then I copied the code from "custom_button.xml" and added it directly without inflating it, I just added the android:onClick parameter and in this way it worked. I can't find out what would be the problem, the layouts are the same.
Has some of you have similar problems? What could be the problem? I attached the code if it helps someone to find the problem.
Thank you for any help!
custom_button.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/button_language_selection_states"
android:weightSum="1"
android:clickable="true"
>
<TextView
android:id="#+id/textview_select_language"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_gravity="center"
android:gravity="center_horizontal"
android:paddingTop="30px"
android:layout_weight="0.4"
android:textSize="21sp"
android:textColor="#333333"
/>
<View
android:layout_width="match_parent"
android:background="#drawable/gradient"
android:layout_height="1dp"
android:layout_margin="10px">
</View>
<TextView
android:id="#+id/textview_language"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_gravity="center"
android:paddingTop="40px"
android:layout_weight="0.6"
android:textSize="28sp"
android:textColor="#ffffff"
/>
</LinearLayout>
ButtonLanguageSelection
public class ButtonLanguageSelection extends LinearLayout
{
private TextView introductoryTextView;
private TextView language;
private final String TAG = "ButtonLanguageSelection";
public ButtonLanguageSelection(Context context) {
super(context);
}
public ButtonLanguageSelection(Context context, AttributeSet attrs)
{
super(context, attrs);
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
layoutInflater.inflate(R.layout.button_language_selection, this);
introductoryTextView = (TextView)findViewById(R.id.textview_select_language);
language = (TextView)findViewById(R.id.textview_language);
this.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "onclick");
}
});
}
public ButtonLanguageSelection(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void setIntroductoryTextView(String s)
{
introductoryTextView.setText(s);
}
public void setLanguage(String s)
{
language.setText(s);
}
}
main_activity.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/screen_welcome_bg">
<defaultpackage.ButtonLanguageSelection
android:id="#+id/ButtonLanguageSelection_Slovene"
android:layout_width="341px"
android:layout_height="260px"
android:layout_marginRight="2px"/>
<defaultpackage.ButtonLanguageSelection
android:id="#+id/ButtonLanguageSelection_Italian"
android:layout_width="341px"
android:layout_height="260px"
android:layout_marginRight="2px"/>
<!--<defaultpackage.ButtonLanguageSelection-->
<!--android:id="#+id/ButtonLanguageSelection_English"-->
<!--android:layout_width="341px"-->
<!--android:layout_height="260px" />-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="341px"
android:layout_height="260px"
android:background="#drawable/button_language_selection_states"
android:weightSum="1"
android:clickable="true"
android:onClick="sendMessage"
>
<TextView
android:id="#+id/textview_select_language"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_gravity="center"
android:gravity="center_horizontal"
android:paddingTop="30px"
android:layout_weight="0.4"
android:textSize="21sp"
android:textColor="#333333"
/>
<View
android:layout_width="match_parent"
android:background="#drawable/gradient"
android:layout_height="1dp"
android:layout_margin="10px">
</View>
<TextView
android:id="#+id/textview_language"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_gravity="center"
android:paddingTop="40px"
android:layout_weight="0.6"
android:textSize="28sp"
android:textColor="#ffffff"
/>
</LinearLayout>
I think the problem is writing all the init code in only one constructor. Consider making an init function and call it from all the constructors. Also consider setting the onClick events listeners in your activity rather than than the layout constructor itself.

Activity with dynamicly added components freezes

My Application freezes and LogCat grows heap (frag case) to 14mb if add more then 3 own "components" to current activity/layout. It takes very long until the fourth "component" is added and Android asks to close my application.
I've written a Activity which has some components (EditTexts) and a own "component". I want to do something similar to the contacts app (Number adding) but with ingredients. So I've created a class IngredientsLayout which extends LinearLayout and a Layout xml file with a TextView and a "Add"-Button which I've placed on the Activity-Layout. Every time I press the Add Button, a single IngredientLayout with 3 EditTexts and a ImageButton will be added to the current IngredientsLayout which should "hold" all added ingredients.
What I'm doing wrong?
IngredientsLayout class:
public class IngredientsLayout extends LinearLayout {
ImageButton imageButtonAddIngredient;
ArrayList<IngredientLayout> arrayList;
public IngredientsLayout(Context context, AttributeSet attrs) {
super(context, attrs);
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.ingredients_list, this);
arrayList = new ArrayList<IngredientLayout>();
imageButtonAddIngredient = (ImageButton) findViewById(R.id.imageButtonAddIngredient);
imageButtonAddIngredient.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
LinearLayout layout = (LinearLayout) findViewById(R.id.linearLayoutIngredientsList);
IngredientLayout ingredientLayout = new IngredientLayout(getContext(), null);
ingredientLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT));
arrayList.add(ingredientLayout);
layout.addView(ingredientLayout);
}
});
}
}
ingredients_layout.xml:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linearLayoutIngredientsList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:orientation="horizontal" >
<TextView
android:id="#+id/textView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="left|center_vertical"
android:layout_weight="1"
android:text="#string/ingredients_list_name" />
<ImageButton
android:id="#+id/imageButtonAddIngredient"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:src="#drawable/ic_menu_add_ingredient" />
</LinearLayout>
</LinearLayout>
</merge>
IngredientLayout class:
public class IngredientLayout extends LinearLayout {
public IngredientLayout(Context context, AttributeSet attrs) {
super(context, attrs);
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.ingredients_list_row, this);
}
}
ingredients_list_row.xml
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linearLayoutIngredientRow"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="#+id/editTextAmount"
android:layout_width="45dp"
android:layout_height="fill_parent"
android:layout_weight="0.11"
android:ems="10"
android:hint="#string/ingredients_list_listrow_amount"
android:inputType="numberDecimal" >
<requestFocus />
</EditText>
<EditText
android:id="#+id/editTextUnit"
android:layout_width="60dp"
android:layout_height="fill_parent"
android:layout_weight="0.06"
android:ems="10"
android:hint="#string/ingredients_list_listrow_unit" /><EditText
android:id="#+id/editTextName"
android:layout_width="127dp"
android:layout_height="match_parent"
android:layout_gravity="left"
android:layout_weight="0.005"
android:ems="10"
android:hint="#string/ingredients_list_listrow_name" />
<ImageButton
android:id="#+id/imageButton1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:src="#drawable/ic_menu_cancel" />
</LinearLayout>
</merge>
LinearLayouts are not meant for this kind of dynamic accessing.
What you need to do is a ListView and a adapter.
And every time you add a new item into the adapter you call it's NottifyDataChanged to update the list view with the new item.

Android. How to adjust height and width of a custom component using XML attributes?

Is there any way to adjust height and width of a custom component using XML attributes?
For example, I created a component and its layout.
Here is XML layout of the component:
<?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="horizontal" >
<TextView
android:id="#+id/textView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:text="TextView" />
<TextView
android:id="#+id/textView2"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:text="TextView" />
<TextView
android:id="#+id/textView3"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:text="TextView" />
</LinearLayout>
And here is a simple class that inflates this layout:
public class CustomComponent extends LinearLayout
{
public CustomComponent(Context context, AttributeSet attrs)
{
super(context, attrs);
LayoutInflater inflater = (LayoutInflater)context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ViewGroup view = (ViewGroup)inflater.inflate(
R.layout.custom_component, null);
addView(view);
}
}
The custom component is used in layout of some activity that looks something like this:
<?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" >
<view
class = "com.tests.CustomComponent"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
The component is meant to be stretched to full size of a screen (that's why its layout parameters set to "fill_parent") but that is never happen.
Can anyone help me with this?
Seeing as your CustomComponent extends LinearLayout, you just need to inflate the layout directly into it (parsing this as the ViewGroup, as your CustomComponent will be the holding view):
public class CustomComponent extends LinearLayout
{
public CustomComponent(Context context, AttributeSet attrs)
{
super(context, attrs);
inflate( context, R.layout.custom_component, this );
}
}
If that doens't work, try supplying only the constructor that takes a context:
public class CustomComponent extends LinearLayout
{
public CustomComponent(Context context)
{
super(context);
inflate( context, R.layout.custom_component, this );
}
}

Categories

Resources