findViewById() returns 自定义视图中的 null
findViewById() returns null from a custom view
我是 Android 编程新手。我有一个 Main Activity 实现了一些 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) {
}
}
主要Activity是这样的:
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
内部设置文本时,它 returns null 并抛出 NullPonterException
.如何从 custom-view
中访问 TextView
?
首先你必须创建一个 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>
然后在 class GameMap 的 init()
方法中初始化你的 custom_layout
:
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");
}
然后在您的 MainActivity layout.xml
中添加您的 custom_layout
<?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 class 中:
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 ...
}
}
我是 Android 编程新手。我有一个 Main Activity 实现了一些 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) {
}
}
主要Activity是这样的:
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
内部设置文本时,它 returns null 并抛出 NullPonterException
.如何从 custom-view
中访问 TextView
?
首先你必须创建一个 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>
然后在 class GameMap 的 init()
方法中初始化你的 custom_layout
:
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");
}
然后在您的 MainActivity layout.xml
中添加您的custom_layout
<?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 class 中:
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 ...
}
}