Как передать AttributeSet в пользовательский вид - PullRequest
28 голосов
/ 14 сентября 2010

Как передать текущий набор атрибутов в пользовательский класс View? Если я использую конструктор, который имеет только Context в аргументах, я теряю все темы и возможность использовать теги "style" в xml для этого пользовательского представления.

То, что я сделал, - это создаю действие, которое уже содержит мой пользовательский вид в файле xml, а затем программно создаю новое и добавляем его в макет. То, что я нахожу, - то, что сделано в xml, имеет надлежащий стиль, а тот, который я создаю программно, - нет.

Насколько я могу судить, разница между ними заключается в том, что система использует конструктор CustomLayout1(Context context, AttributeSet attrs). Проблема в том, что я не могу понять, как заставить AttributeSet для приложения перейти к этому пользовательскому представлению при его программном создании.

Вот активность:

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);

        layout.addView(new CustomLayout1(getApplicationContext()));
    }
}

Вот основной 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>

Класс пользовательского представления:

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);
 }
}

и, наконец, пользовательское представление 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>

Ответы [ 3 ]

27 голосов
/ 14 сентября 2010

Вместо того, чтобы создавать его с layout.addView (новый CustomLayout1 (getApplicationContext ())); надуйте его с помощью LayoutInflater в вашей активности.

LayoutInflater inflater = LayoutInflater.from(this);
inflater.inflate(R.layout.yourcustomviewxml, layout);
3 голосов
/ 21 июля 2011

Ваш код создает LinearLayout внутри линейного макета для вашего пользовательского представления. Правильный способ сделать это - изменить свой пользовательский вид 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>

до

<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>
2 голосов
/ 14 сентября 2010

Чего ты здесь пытаешься достичь? Похоже, у вас есть бесконечный рекурсивный цикл с использованием вашего метода create, поскольку inflate () вызовет конструктор, который принимает атрибуты. В любом случае, чтобы ответить на ваш вопрос, вы получите атрибуты в конструкторе с атрибутами!

Это конструктор, который вызывается при загрузке из XML, в противном случае он вызывает один из других предоставленных вами конструкторов.

Еще одна полезная вещь: вы можете получить ссылку на инфлятор гораздо проще с помощью статического метода View. View.inflate: D

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...