开发者

How to pass AttributeSet to custom View

开发者 https://www.devze.com 2023-01-16 13:38 出处:网络
How do I pass the current AttributeSet to a custom View class? If I use a constructor that only has Context in the arguments, I lose all themes and the ability to use \"style\" tags in the xml for tha

How do I pass the current AttributeSet to a custom View class? If I use a constructor that only has Context in the arguments, I lose all themes and the ability to use "style" tags in the xml for that custom View.

What I've done is create an activity that contains my custom view already in the xml file, and then programmatically create a new one and add it to the layout. What I find is the one that is made in the xml has the proper styling, and the one I create programmatically doesn't.

The difference between the two as far as I can tell is that the system uses the CustomLayout1(Context context, AttributeSet attrs) constructor. The problem is I can't figure out how to get the AttributeSet for the application to pass to this custom view when I create it programmatically.

Here's the Activity:

import android.app.Activity;
import android.os.Bundle;
import android.widget.LinearLayout;

public class ThemeOne extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        LinearLayout layout = (LinearLayout) findViewById(R.id.mainlayout);

        layou开发者_Python百科t.addView(new CustomLayout1(getApplicationContext()));
    }
}

Here's the main xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="vertical" 
 android:id="@+id/mainlayout"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent">
 <com.clearsync.test.theme1.CustomLayout1 android:id="@+id/maincustom"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content" />
</LinearLayout>

The custom view class:

import com.clearsync.test.theme1.R;

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.LinearLayout;

public class CustomLayout1 extends LinearLayout {
 private Context context = null;

 public CustomLayout1(Context context) {
  super(context);
  this.context = context;
  create();
 }

 public CustomLayout1(Context context, AttributeSet attrs) {
  super(context, attrs);
  this.context = context;
  create();
 }

 private void create(){
  LayoutInflater layoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  layoutInflater.inflate(R.layout.inflateme, this, true);
 }
}

and finally, the custom view xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="vertical" 
 android:layout_width="fill_parent"
 android:layout_height="fill_parent">
 <TextView android:layout_width="wrap_content"
  android:layout_height="wrap_content" 
  android:text="Oh, Hewroh..."
  style="?textview_style1" />
</LinearLayout>


Instead of building it with layout.addView(new CustomLayout1(getApplicationContext())); inflate it with the LayoutInflater in your Activity.

LayoutInflater inflater = LayoutInflater.from(this);
inflater.inflate(R.layout.yourcustomviewxml, layout);


Your code creates LinearLayout inside of linear layout for your custom view. Correct way of doing this is changing your custom view xml from:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="vertical" 
 android:layout_width="fill_parent"
 android:layout_height="fill_parent">
 <TextView android:layout_width="wrap_content"
  android:layout_height="wrap_content" 
  android:text="Oh, Hewroh..."
  style="?textview_style1" />
</LinearLayout>

to

<merge xmlns:android="http://schemas.android.com/apk/res/android">
<TextView android:layout_width="wrap_content"
      android:layout_height="wrap_content" 
      android:text="Oh, Hewroh..."
      style="?textview_style1" 
/>
</merge>


What are you trying to accomplish here? Looks like you have an endless recursive loop here using your create method, as inflate() will call the constructor that takes attributes. Anyways to answer your question you get the attributes in the constructor with the attributes!

That is the constructor that is called when loading from XML, otherwise it calls one of the other constructors that you supply.

One other helpful thing, you can get a reference to the inflater much easier from the static View method. View.inflate :D

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号