findViewById () возвращает ноль из пользовательского представления - PullRequest
0 голосов
/ 10 мая 2019

Я новичок в программировании Android. У меня есть основной вид деятельности, который реализует макет с некоторыми TextView и custom-view. Макет такой:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">


<TextView
    android:id="@+id/turnTextView"
    //and other tags
    />

    <com.example.crosstheboxprova.GameMap
    android:id="@+id/gameMapView"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:layout_marginStart="0dp"
    android:layout_marginLeft="0dp"
    android:layout_marginTop="0dp"
    android:layout_marginEnd="0dp"
    android:layout_marginRight="0dp"
    android:layout_marginBottom="0dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/turnTextView" />

</android.support.constraint.ConstraintLayout>

custom-view выглядит примерно так:

public class GameMap extends View {

private TextView tv;


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

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

public GameMap(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init(context);
}

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public GameMap(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
    init(context);
}

private void init(Context context){
    //do I have to use the context in some way? 
    //here or on other part of the class I need something like:
    tv = findViewById(R.id.turnTextView); //returns null
    tv.setText("hello");
}



@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    /***/
}



@Override
public boolean onTouchEvent(MotionEvent event) {

}

}

и MainActivity это:

public class MainActivity extends AppCompatActivity {
private GameMap gameMap;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
    setContentView(R.layout.activity_main);
    gameMap = new GameMap(this);

}
}

проблема в том, что когда я вызываю FindViewById() для доступа к TextView и устанавливаю текст внутри custom-view, он возвращает ноль и выдает NullPonterException. Как я могу получить доступ к TextView изнутри custom-view?

1 Ответ

1 голос
/ 10 мая 2019

Сначала вы должны создать custom_layout.xml и поместить свой TextView и любой виджет, который хотите использовать следующим образом:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/txt"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

, а затем инициализировать свой custom_layout в init() метод класса GameMap.:

public class GameMap extends LinearLayout {
.
.
.

     private void init(Context context) {

            View rootView = inflate(context, R.layout.sampel, this);
            tv = rootView.findViewById(R.id.txt);
            tv.setText("hello");
        }

затем добавьте custom_layout в свой файл MainActivity layout.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">


    <com.example.crosstheboxprova.GameMap
    android:id="@+id/gameMapView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    />

</android.support.constraint.ConstraintLayout>

и в свой класс MainActivity:

public class MainActivity extends AppCompatActivity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_main);

        GameMap gameMap = (GameMap) findViewById(R.id.gameMapView);

//        And continue the code ...
    }
}
...