如何从充气的布局中访问视图?

4
我有一个简单的Activity,它附带了main.xml。main.xml具有自定义布局(customLinearLayout)和一个简单的TextView。自定义布局也有它自己的布局文件(linearlayout.xml),其中包含一个简单的Button。该布局被类正确地膨胀。 linearlayout.xml中的Button应更改位于main.xml中的textView的文本,但我无法访问该textView。我做错了什么?我也无法膨胀main.xml。
这是customLinearLayout:
public class CustomLinearLayout extends LinearLayout {

LayoutInflater mInflater;
View ContainerView;

Button button1;
TextView tv;

public CustomLinearLayout(Context context) {
    super(context);
    // TODO Auto-generated constructor stub
    init();
}

public CustomLinearLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
    // TODO Auto-generated constructor stub
    init();
}

private void init() {
    mInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    ContainerView = mInflater.inflate(R.layout.linearlayout, this, true);

    button1 = (Button) ContainerView.findViewById(R.id.button1);

    // trying to get the TextView from main.xml
    tv = (TextView) ContainerView.findViewById(R.id.textview1); // doesn't work

    // these tries doesn't work either
    //tv = (TextView) ContainerView.getRootView().findViewById(R.id.textview);  
    //tv = (TextView) this.getRootView().findViewById(R.id.textview);
    //tv = (TextView) this.findViewById(R.id.textview);

    button1.setOnClickListener(new Button.OnClickListener() {
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if(tv != null)
                tv.setText("works");
            else
                Log.d("CustomLinearLayout", "TextView not found");
        }
    });
}
}

布局文件(linearlayout.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="match_parent"
android:orientation="vertical" >

<Button
    android:id="@+id/button1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="press" />

</LinearLayout>

活动:

public class TestLayoutViewsv2Activity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
}
}

活动的 main.xml 文件:
<?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" >

<test.layoutviewsv2.CustomLinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

<TextView
    android:id="@+id/textview1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

</LinearLayout>
2个回答

2
方法findViewById是有范围的 - 您的自定义视图正在查找一个不存在的文本字段。但没关系!您的视图应该是自己的小世界 - 它们不需要了解自身外部的任何内容。不幸的是,您将不得不更改设计以适应此(例如通过回调到活动),以使其按照您的意愿工作。

1
谢谢您的回答!我想我的想法是错误的。我假设视图在膨胀后会加入main.xml,以便我可以返回层次结构。我猜我得读一下有关使用回调的资料了。除了使用回调之外,还有其他方法可以让一个视图知道另一个视图已经更改了吗?(例如,当另一个视图或类完成任务时,告诉按钮返回其初始状态) - user1349812
@user1349812 不,那基本上是唯一的方法 -> 您的活动管理其所有视图的状态。就像我说的,视图存在于自己的小世界中 - 它可以告诉母船发生了什么事情,母船的工作是确保所有相关的其他视图根据接收到的信息进行更改。 - JRaymond
但这是否意味着只有一个层次结构控制所有的UI?拆分UI为一些ViewGroups的想法如何,以避免过载活动?这是如何处理的? - 最后一个问题,我保证 :) - user1349812
1
如果您的ViewGroups被自定义,它们可以控制其子项的行为,因此如果对子项A的操作应影响子项B,则ViewGroup可以管理该操作,但信息流实际上只能沿树向上或向下流动,而不能跳过分支。至于避免过载活动,请尝试使用片段:http://developer.android.com/guide/topics/fundamentals/fragments.html 即使您正在开发旧平台,它们也已通过支持包集成到其中。 - JRaymond
非常感谢!你真的帮了我很大的忙。而且我不知道片段可以在旧版本中使用。我也会考虑这个问题。 - user1349812

0

您正在错误地使用inflate方法。如果您正在扩展视图,则没有充气布局的意义。inflate方法用于初始化新视图,而无需自己创建新实例。我不知道您想要做什么,但是您可以使用include来重用一些布局。请查看此链接以获取更多信息http://developer.android.com/resources/articles/layout-tricks-merge.html


是的,那只是我实际遇到的问题的一个简单示例。我只想让一个视图知道另一个视图已经改变了它的状态(就像告诉一个激活的按钮在另一个视图或类完成工作后切换回其初始状态)。通过膨胀,我认为我可以访问放置在布局中的视图,以便我可以以编程方式获取它们的状态。 - user1349812

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接