我是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
内部设置文本时,它返回null并抛出NullPonterException
。如何从TextView
内部访问custom-view
?
答案 0 :(得分:1)
首先,您必须创建一个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>
然后使用GameMap类的custom_layout
方法初始化您的init()
:
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 ...
}
}