Android не может найти вид по идентификатору во фрагменте

1

У меня есть собственный EditText MomentumEditText который у меня есть в макете в xml (fragment_edit_text.xml):

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.frazerm.momentum.MomentumEditText
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/writing_edittext"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</RelativeLayout>

Я могу успешно раздуть и отобразить макет в фрагменте, но попытка получить MomentumEditText с помощью View.findViewById(R.id.writing_edittext) возвращает null.

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View root = inflater.inflate(R.layout.fragment_edit_text, container, true);
    MomentumEditText editText = (MomentumEditText) root.findViewById(R.id.writing_edittext);
}

Я также попытался получить MomentumEditText из onStart(), но он все равно возвращает null.

Edit= Я попытался заменить пользовательский EditText в xml простым EditText, и findViewById() работает! здесь MomentumEditText:

package com.frazerm.momentum;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.MotionEvent;
import android.widget.EditText;

public class MomentumEditText extends EditText  {

boolean moveCursorDisabled = true;
boolean deleteCharsDisabled = true;

private static Paint linePaint;
private static Paint marginPaint;
MomentumEditText thisEditText = this;

Editable currentText;

public MomentumEditText(Context context, AttributeSet attrs) {
    super(context);

    setCursorVisible(true);
    this.setGravity(Gravity.TOP);
    TextWatcher inputTextWatcher = new TextWatcher() {
        CharSequence textToAdd = "";
        boolean charWasDeleted = false;
        public void beforeTextChanged(CharSequence s, int start, int count, int after)  {
            if (moveCursorDisabled) {
                if( count > after ) {
                    textToAdd = s.subSequence(start + after, start + count);
                    charWasDeleted = true;
                }
            }
        }

        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        @Override
        public void afterTextChanged(Editable s)    {
            if (moveCursorDisabled) {
                if (charWasDeleted == true) {
                    charWasDeleted = false;
                    s.append(textToAdd);
                }
                else    {
                    thisEditText.setSelection( thisEditText.getText().length() );
                }
            }
        }

    };
    this.addTextChangedListener(inputTextWatcher);

}

//disables ability to move the cursor to other parts of the text
@Override
public boolean onTouchEvent(MotionEvent event)
{
    if (deleteCharsDisabled)    {
        final float eventX = event.getX();
        if( getSelectionStart() != eventX )
        {
            super.onTouchEvent(event);
            thisEditText.setSelection( thisEditText.getText().length() );
            return true;
        }
        return super.onTouchEvent(event);
    }
    return super.onTouchEvent(event);
}

@Override
protected void onDraw(Canvas canvas) {
    linePaint = new Paint();
    linePaint.setColor(0x77777777);
    //linePaint.setStyle(Style.STROKE);

    marginPaint = new Paint();
    marginPaint.setColor(0x99FF4444);
    //marginPaint.setStyle(Style.STROKE);

    Rect bounds = new Rect();
    int firstLineY = getLineBounds(0, bounds);
    int lineHeight = getLineHeight();
    int totalLines = Math.max(getLineCount(), getHeight() / lineHeight);

    for (int i = 0; i < totalLines; i++) {
        int lineY = firstLineY + i * lineHeight + dip(2);
        canvas.drawLine(0, lineY, bounds.right, lineY, linePaint);
    }


    canvas.drawLine( (float) dip(64), (float) 0, (float) dip(64), getHeight(), marginPaint );

    super.onDraw(canvas);
    setPadding(dip(64), 0, 0, 0);
}

public void setCursorMoveAllowed(boolean allowed)   {
    moveCursorDisabled = !allowed;
    setCursorVisible(allowed);
    return;
}

public void setBackspaceAllowed(boolean allowed)    {
    deleteCharsDisabled = !allowed;
    return;
}

public boolean superTouchEvent(MotionEvent event)   {
    return super.onTouchEvent(event);
}

public int dip ( int dip )  {
    float d = this.getResources().getDisplayMetrics().density;
    int pixels = (int)(dip * d);        
    return pixels;

}

}
  • 0
    Вам нужно только xmlns:android="http://schemas.android.com/apk/res/android" в вашем корневом элементе, кстати.
  • 0
    Да, где-то было предложено, чтобы установка пользовательских представлений решала эту проблему, но это не
Показать ещё 2 комментария
Теги:
android-fragments
findviewbyid

4 ответа

1
Лучший ответ

Поскольку вы расширяете текущий вид, вам необходимо переопределить все используемые конструкторы. Пытаться:

public class MomentumEditText extends EditText  {

    public MomentumEditText(Context context) {
        super(context);
        init();
    }

    public MomentumEditText(Context context, AttributeSet attrs) {
        super(context, attrs); // This is the constructor used by XML (you were missing the super call)
        init();
    }

    public MomentumEditText(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defstyle);
        init();
    }

    private void init(){
         setCursorVisible(true);
         // your other code
    }
}

Ссылка: http://developer.android.com/reference/android/widget/EditText.html (публичные конструкторы)

4

Попробуйте настроить attach на root false, так как вы являетесь корнем!

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View root = inflater.inflate(R.layout.fragment_edit_text, container, false);

    MomentumEditText editText = (MomentumEditText) root.findViewById(R.id.writing_edittext);

    return root;
}
  • 0
    Это должно сделать это.
  • 0
    Это тоже не сработало
1

Попробуйте переместить эту строку кода в свой метод onActivityCreated:

MomentumEditText editText = (MomentumEditText) findViewById(R.id.writing_edittext);
0

Я предполагаю, что fragment_edit_text.xml - это файл макета, который вы указали в своем вопросе?

Если да, проверьте, нет ли другого макета с тем же именем в некоторых папках, где указаны некоторые конфигурации (например, язык, плотность и т.д.).

Например, у вас могут быть:

/layout/fragment_edit_text.xml

а также

/layout-land/fragment_edit_text.xml

но только ваш пользовательский вид в каталоге layout-land, поэтому он будет компилироваться нормально, но когда в портретном режиме ваш findViewById вернет значение null

  • 0
    Нет Компоновка раздувается и отображается правильно, это editText = (MomentumEditText) root.findViewById(R.id.writing_edittext); который возвращает ноль
  • 0
    @ Frazerm63 да, он говорит, что он вернет ноль, если у вас есть fragment_edit_text.xml в /layout/ и /layout-land/ но только ваш MomentumEditText в XML-файле папок layout-land
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню