Android Studio如何使自定义视图可滚动?

3

我正试图在主线性布局中放置一个滚动视图,在滚动视图内部有一个包含自定义视图的线性布局,我不太确定该如何使其工作。 我是Android Studio的新手,如果您能指出我的错误,我将不胜感激。谢谢! 代码在我的自定义视图类中看起来像这样

package com.example.myapplication;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

public class mview extends View {

    public int lines = 0;
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    public void addLine(){
        postInvalidate();
        lines++;
    }
    public mview(Context context) {
        super(context);
        init(null, 0);
    }
    public mview(Context context, AttributeSet attr) {
        super(context, attr);
        init(attr, 0);
    }
    public mview(Context context, AttributeSet attr, int def) {
        super(context, attr, def);
        init(attr, def);
    }
    private void init(AttributeSet set, int def) {
        line1.setColor(Color.BLACK);
        line1.setAntiAlias(true);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //draw grids
        for (int i = 0; i < lines; i++) {
        canvas.drawLine(...);
        }
    }
}

我的MainActivity类中的代码长这样:

package com.example.myapplication;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    private void clicked() {
        mview.addLine();
    }
    private mview mview;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mview = findViewById(R.id.mview);
        setContentView(R.layout.activity_main);
        ScrollView scrollView = findViewById(R.id.scrollview);
        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                clicked();
            }
        });
    }
}

我的activity_main布局长这样:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <ScrollView
            android:id="@+id/scrollview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">

                <com.example.myapplication.mview
                    android:id="@+id/mview"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent" />

            </LinearLayout>
        </ScrollView>

        <Button
            android:id="@+id/button"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:text="Button" />


    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

谢谢!我删除了权重并将高度设置为mview的包裹内容。但是每次我点击按钮时,它都会崩溃并显示ava.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.myapplication.mview.addLine()' on a null object reference,而它应该向mview的画布添加新行。 - Yuchen Huang
2个回答

1

您的线性布局视图永远不会滚动,因为您已将自定义视图的高度设置为match_parent,您必须将其更改为wrap_content。

        <com.example.myapplication.mview
            android:id="@+id/mview"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

to

            <com.example.myapplication.mview
                android:id="@+id/mview"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

将findViewById移动到setContentView之后。
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);   //moved up
    mview = findViewById(R.id.mview);       //moved down
    ScrollView scrollView = findViewById(R.id.scrollview);
    Button button = findViewById(R.id.button);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            clicked();
        }
    });
}

谢谢!我删除了权重并将mview的高度设置为自动包裹内容。但是每次我点击按钮时它都会崩溃,并显示ava.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.myapplication.mview.addLine()' on a null object reference,当它应该向mview的画布添加新行时。 - Yuchen Huang
您的mview为空,可以通过抛出“NullPointerException”异常来解决此问题:由于活动视图为空并且findViewById找不到该视图,因此您可以在setContentView之后使用findViewById。因此,您必须将“mview = findViewById(R.id.mview);”移动到“setContentView(R.layout.activity_main);”之后。 - ZIRES

0

不用担心。只是有一个小错误,如下所述,当您考虑Layout_weight = 1时,高度与全屏高度匹配,因此请从代码中删除该属性:

 <ScrollView
            android:id="@+id/scrollview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"          // Remove this line from here
              >  

谢谢!我删除了权重并将高度设置为mview的包装内容。但是每次我点击按钮它都会崩溃,并显示ava.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.myapplication.mview.addLine()' on a null object reference,而实际上它应该向mview的画布添加新行。 - Yuchen Huang

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接