如何从片段内检索自定义视图的引用

时间:2014-02-12 18:48:31

标签: android view android-fragments

我有一个自定义视图,我想在片段中使用。与该View交互的逻辑应该驻留在Fragment(或该片段拥有的对象)中。在片段的onCreateView方法中,我膨胀片段布局。紧接着,我试图获得对布局中使用的BadgeButton的引用。

我看到的问题是我无法获得对自定义视图的引用。如下所示注释掉两行,Activity将正确加载并正确显示BadgeButton。

当我从这个示例中删除Fragment并将其布局合并到MainActivity的布局时,它能够很好地获得引用。这种行为的原因是什么?

MainActivity

public class MainActivity extends Activity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    if (savedInstanceState == null) {
      getFragmentManager().beginTransaction()
        .add(R.id.container, new MainFragment())
        .commit();
    }
  }
}

MainFragment

public class MainFragment extends Fragment {
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_main, container, false);
    // BadgeButton badger = (BadgeButton) this.getActivity().findViewById(R.id.badger);
    // badger.setBadgeText("example"); // NullPointerException
    return rootView;
  }
}

BadgeButton

public class BadgeButton extends FrameLayout {
  private TextView mBadgeTextView;

  public BadgeButton(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(context);
  }

  public void setBadgeText(String value) {
    mBadgeTextView.setText(value);
  }

  private void init(Context context) {
    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View inflate = inflater.inflate(R.layout.badge_button, this, true);
    mBadgeTextView = (TextView) getChildAt(1);
    mBadgeTextView.setText("0");
  }
}

badge_button.xml

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
  <Button
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"/>
  <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="top|left"
    android:textSize="18sp"
    android:text="123"/>
</merge>

fragment_main.xml

<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical"
  android:paddingLeft="@dimen/activity_horizontal_margin"
  android:paddingRight="@dimen/activity_horizontal_margin"
  android:paddingTop="@dimen/activity_vertical_margin"
  android:paddingBottom="@dimen/activity_vertical_margin"
  tools:context="com.example.badgebutton.MainFragment">

  <com.example.badgebutton.BadgeButton
    android:id="@+id/badger"
    android:layout_width="120dp"
    android:layout_height="120dp"/>

</LinearLayout>

activity_main.xml中

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.badgebutton.MainActivity"
    tools:ignore="MergeRootFrame" />

如果您对此问题的质量有任何意见或有关如何改进此问题和未来问题的建议,请告诉我(以适当的方式)。我想问一些好问题,并成为社区的宝贵贡献者。谢谢。

1 个答案:

答案 0 :(得分:1)

BadgeButton badger = (BadgeButton) rootView.findViewById(R.id.badger);
badger.setBadgeText("example");

使用此选项,因为该视图与Fragment而不是Activity

相关联