情况:我的布局中有一些自定义组件。我有一个公共布局框架,我在我的Activity基类的onCreate()
中加载,然后使用inflater在我的实现中加载我的内容布局,将根设置为主布局的内容列。
问题:当我获取对视图的引用时,为了实际提取用户的输入,Activity.findViewById()
返回null
。这可能是一个线索,我在布局中的CheckBox和Button不会返回null
;我得到了对小部件的有效引用。
我尝试过的事情:我知道我正在正确加载和扩充布局xml,因为一切都显示出来了,ID可以找到相同布局的标准视图。我可以与我的视图进行交互,并将内容放入它们和所有内容中,但我无法在代码中获得对它们的引用。
我多次尝试清理项目。 R.id
是新鲜的,是最新的。
我检查了控制台和错误日志,并且没有报告UI / XML错误。
我尝试获取为此活动加载的内容的根布局的句柄,并调用View.findViewById()
来获取我的引用,并返回null
。如果我在调试器中检查布局,我可以向下钻取并在mChildren
中找到我的视图。
也许是另一条线索:
public VideoChooser(Context pCtxt, AttributeSet pAttrs)
{
super(pCtxt, pAttrs);
Log.d("VideoChooser", "Expected ID: " + R.id.vchShareVids + " | actual: " + getId());
}
将产生以下输出:
DEBUG/VideoChooser(10372): Expected ID: 2131296271 | actual: 268435456
分配给视图的ID与R.id
中的ID不匹配!那为什么会这样?我知道它正在加载android:id
属性,否则它将为-1(View.NO_ID
)。
公共布局框架:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:foo="http://schemas.android.com/apk/res/com.foo"
android:id="@+id/common_frame" android:orientation="vertical"
android:layout_width="match_parent" android:layout_height="match_parent">
<!-- top banner -->
<LinearLayout android:id="@+id/frame_header" android:orientation="horizontal"
android:layout_height="wrap_content" android:layout_width="match_parent"
android:layout_marginBottom="16dp">
<ImageView android:src="@drawable/banner"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" android:layout_weight="1" />
</LinearLayout>
<!-- content column -->
<LinearLayout android:id="@+id/frame_content" android:orientation="vertical"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_marginLeft="32dp" android:layout_marginRight="32dp" />
</LinearLayout>
内容布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:foo="http://schemas.android.com/apk/res/com.foo"
android:id="@+id/content_panel" android:orientation="vertical"
android:layout_width="match_parent" android:layout_height="match_parent">
<com.foo.view.VideoChooser android:id="@+id/vchShareVids"
foo:prompt_text="@string/prompt_share_vid" foo:prompt_size="16dp"
foo:preview_height="80dp"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_marginBottom="12dp" android:hapticFeedbackEnabled="true" />
<com.foo.view.ContactChooser android:id="@+id/cchRecipients"
foo:prompt_text="@string/prompt_share_email" foo:prompt_size="16dp"
foo:preview_lines="3" foo:dialog_title="Pretend you are picking contacts"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_marginBottom="12dp" android:hapticFeedbackEnabled="true" />
<com.foo.view.TextChooser android:id="@+id/tchDescription"
foo:prompt_text="@string/prompt_share_description" foo:prompt_size="16dp"
foo:preview_lines="1" foo:dialog_title="@string/title_msg_chooser_dlg"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_marginBottom="12dp" android:hapticFeedbackEnabled="true" />
<CheckBox android:id="@+id/chkReshare" android:text="@string/prompt_reshare"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:checked="true" android:hapticFeedbackEnabled="true" />
<Button android:id="@+id/btnSend" android:text="@string/btn_send"
android:layout_width="@dimen/btn_width" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" android:hapticFeedbackEnabled="true" />
</LinearLayout>
活动基类onCreate():
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.common_frame);
}
活动实施onCreate():
@Override
protected void onCreate(Bundle pState)
{
super.onCreate(pState);
load_content_view(R.layout.content_layout);
ViewGroup tLayout = (ViewGroup)findViewById(R.id.content_panel);
// These all return null
mCchVideo = (ContentChooser)tLayout.findViewById(R.id.vchShareVids);
mCchContact = (ContentChooser)tLayout.findViewById(R.id.cchRecipients);
mCchDescription = (ContentChooser)tLayout.findViewById(R.id.tchDescription);
// These return valid references
mChkReshare = (CheckBox)findViewById(R.id.chkReshare);
mBtnSend = (Button)findViewById(R.id.btnSend);
// ...
}
protected void load_content_view(int pResId)
{
LinearLayout tColumn = (LinearLayout)findViewById(R.id.frame_content);
getLayoutInflater().inflate(pResId, tColumn);
}
答案 0 :(得分:13)
我遇到了类似的问题,我的解决方案是确保自定义窗口小部件的构造函数调用
super(context, attrs);
我的构造函数没有将attrs传递给super,因此视图id被搞砸了,findviewbyId返回null。
答案 1 :(得分:1)
如果没有实际来源,很难找到问题。我已根据您的帖子创建了示例项目,并且已完全正常运行。 我相信有一个非常简单的错误,你会发现它。 如果您愿意,可以try it
答案 2 :(得分:1)
捂脸