Reputation: 8291
I have the following code and my problem is findviewbyid is returning null.
<es.ric.firebase.chat.core.views.chatbox.ChatBox
android:id="@+id/chatbox"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<LinearLayout
android:id="@+id/ll_text"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1">
<EditText
android:id="@+id/messageEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:layout_gravity="center_vertical"
android:paddingLeft="15dp"
android:hint="Escribir mensaje"
android:background="@drawable/background_chat"/>
<ImageButton
android:id="@+id/bt_upload_picture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_insert_photo_black_24dp"
android:background="@android:color/transparent"
android:layout_alignParentEnd="true"
android:layout_centerInParent="true"
android:layout_marginRight="10dp"/>
</RelativeLayout>
<ImageButton
android:id="@+id/sendButton"
android:layout_width="36dp"
android:layout_height="36dp"
android:src="@drawable/ic_send_white_24dp"
android:background="@drawable/background_circle"
android:layout_gravity="bottom"/>
</LinearLayout>
</es.ric.firebase.chat.core.views.chatbox.ChatBox>
Java class.
public class ChatBox extends LinearLayout {
enum State { MODE_MESSAGE, MODE_AUDIO, MODE_RECORDING }
private EditText messageEditText;
private ImageButton bt_upload_picture;
private ImageButton sendButton;
private WeakReference<ChatBoxListener> weak_listener;
private State state;
public ChatBox(Context context) {
super(context);
init();
}
public ChatBox(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public ChatBox(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public ChatBox(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
private void init(){
messageEditText = findViewById(R.id.messageEditText);
bt_upload_picture = findViewById(R.id.bt_upload_picture);
sendButton = findViewById(R.id.sendButton);
}
}
Upvotes: 0
Views: 666
Reputation: 1214
It can't find the view because your view doesn't exist yet. At the point of your init function only the object is already created.
You will need to provide a globalLayoutListener which will notify you when your layout is ready. To do this implement ViewTreeObserver.OnGlobalLayoutListener
In your init function attach the listener
private void init(){
this.getViewTreeObserver().addOnGlobalLayoutListener(this)
}
And finally call findViewById in onGlobalLayout
@Override
public void onGlobalLayout(){
messageEditText = findViewById(R.id.messageEditText);
bt_upload_picture = findViewById(R.id.bt_upload_picture);
sendButton = findViewById(R.id.sendButton);
}
Upvotes: 0
Reputation: 152817
When your custom view constructor runs and you call init()
the child views are not yet instantiated nor added to your ChatBox
layout.
Having dependencies from viewgroup to specific children declared in the same layout is not a good idea anyway. You have unnecessary coupling between ChatBox
and where it is used.
You could wait for inflation to finish but for dependency reasons I'd refactor it towards the following:
Pull out the child views from the layout where you're using ChatBox
and move them to a layout of their own.
Make ChatBox
inflate that layout and add the views to itself. (Use this
as the second root view argument to inflate()
.)
After that you can find the children inside your ChatBox
.
Upvotes: 0
Reputation: 7257
You can access the subviews after the onFinishInflate
method is called:
@Override
protected void onFinishInflate() {
init();
}
Upvotes: 1