Android Studio: Memanggil beberapa Canvas di ScrollView untuk menampilkan 1 gambar (kanvas) demi gambar lainnya

Saya sedang menulis kode untuk proyek sekolah di mana seseorang harus memuat file data (file CSV, file teks, dll) dan dari data yang diperoleh, aplikasi akan meneruskan data ke Tampilan undian khusus dan metode onDraw akan menggambar /plot grafik berdasarkan data.

Tujuan saya adalah agar aplikasi menampilkan 2 grafik, satu demi satu (bertumpuk). Kumpulan data pertama dimuat dan grafik pertama digambar. Data yang dimuat kemudian digunakan untuk penghitungan berbeda dengan metode berbeda. Tampilan gambar khusus kemudian dipanggil lagi dengan data baru untuk menggambar grafik ke-2.

Saat saya menjalankan aplikasi, kedua bagan digambar tetapi karena sumbu x dan y dari grafik diberi kode untuk digambar pada piksel tetap tertentu, grafik ke-2 digambar di atas grafik pertama dan oleh karena itu hanya grafik ke-2 yang terlihat.

Apakah ada cara untuk menggambar 2 grafik tersebut agar tidak tumpang tindih dan malah tampak bertumpuk di ScrollView?

Kode saya ditampilkan di bawah tetapi saya telah menghilangkan perhitungan yang menurut saya tidak terlalu penting. Bantuan dan petunjuk apa pun akan sangat dihargai!

Aktivitas Utama.java:

    @Override
    protected void onActivityResult(......) {
        super.onActivityResult(......);
        switch (1) {
            case 1:
                Graph graph = this.findViewById(R.id.graph1);
                graph.setData(data); // the loaded data is passed to Graph View
                Graph drawGraph2 = this.findViewById(R.id.graph2);
                graph2.setData(this.newCalculate(data));
                break;
        }
    }

Grafik.java

    public  class Graph extends View {
    private Paint mPaint = new Paint();
    private final int zero = 700; // mark the 0 line of graph at 700 pixels


    public void setData(data){   
        ......
    }

    public Graph(Context context, AttributeSet attributeSet) {
        super(context, attributeSet);

    }

    @Override
    protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        setMeasuredDimension(widthSize, heightSize);
    }

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

        plotUnit(canvas);    // plot points on graph

        axisLabel(canvas);    // label axis

        axisLine(canvas);     // draw axis

        xyAxisMarker(canvas);    // mark axis
    }

    private void plotUnit(Canvas canvas) {
        ......
        // Due to data having negative values, the graph is inverted and the 0 starts
        // of the graph is defined at 700 pixels (private final int zero)
    }

    private void axisLabel(Canvas canvas) {
        ......
    }

    private void axisLine(Canvas canvas, int inset) {
        ......
    }

    private void xyAxisMarker(Canvas canvas) {
        ......
    }

Memperbarui

aktivitas_main.xml

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

        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent">

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

                <Button
                    android:id="@+id/loadbutton"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="Open Data File" />

                <firstapp.drawtwograph.Graph
                    android:id="@+id/graph1"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent" />

                <firstapp.drawtwograph.Graph
                    android:id="@+id/graph2"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent" />
            </LinearLayout>
        </ScrollView>
    </LinearLayout>

person Jaclyn    schedule 15.07.2020    source sumber
comment
Posting tata letak XML Anda. Masalahnya mungkin ada di sana.   -  person Jenea Vranceanu    schedule 15.07.2020
comment
@JeneaVranceanu Saya telah mengedit postingan dan menambahkan tata letak XML saya   -  person Jaclyn    schedule 17.07.2020


Jawaban (1)


Anda tidak boleh mencocokkan ketinggian dua tampilan dengan tinggi induk di dalam LinearLayout dengan orientasi vertikal. Hal ini tidak mungkin karena tinggi pandangan ini harus sama dengan tinggi induknya tetapi pada saat yang sama, harus diurutkan satu demi satu sehingga menghasilkan dua kali lipat tinggi induk.

Jika Anda membayangkan tinggi badan orang tua sebagai 10dp maka setiap tampilan Graph harus 10dp juga yang berarti tinggi badan orang tua harus 20dp, bukan 10dp. Itu akan berputar selamanya sehingga Android melakukan hal sederhana: tampilan yang berada di bawah tampilan anak pertama dengan android:layout_height="match_parent" akan memiliki tinggi 0dp atau jika tingginya tetap, tampilan tersebut akan digambar di luar tata letak dan tidak akan terlihat.

Contoh

Contoh masalah

Tangkapan layar dari tab Desain editor tata letak di Android Studio IDE.

Di sini Anda dapat melihat:

  • tampilan merah sebagai tata letak linier induk;
  • tampilan ungu sebagai anak pertama dengan tinggi badan yang sesuai dengan tinggi induknya;
  • tampilan garis luar yang digambar di luar tata letak karena didorong keluar oleh anak pertama dengan android:layout_height="match_parent";
  • ada satu tampilan lagi yang dihancurkan hingga ketinggian 0 sehingga tidak terlihat. Anda dapat melihatnya di kode XML.

Kode XML contoh ini:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="100dp"
    android:background="@android:color/holo_red_light">

    <LinearLayout
        android:background="@color/colorPrimary"
        android:layout_width="60dp"
        android:layout_height="match_parent" <!-- this view's height is a problem -->
        android:orientation="vertical"/>

    <LinearLayout
        android:background="@android:color/holo_green_dark"
        android:layout_width="120dp"
        android:layout_height="match_parent" <!-- height is not fixed, then it will be 0 -->
        android:orientation="vertical"/>

    <LinearLayout
        android:background="@android:color/holo_green_light"
        android:layout_width="120dp"
        android:layout_height="40dp" <!-- height is fixed, it is outlined outside of a layout -->
        android:orientation="vertical"/>

</LinearLayout>

Bagaimana cara memperbaiki masalah ini?

  1. Tetapkan ketinggian tetap. Sebagai ujian, cobalah untuk menentukan ketinggian tetap, mis. 100dp;
  2. Desain ulang tata letak Anda. Gunakan RelativeLayout atau ConstraintLayout untuk memosisikan tampilan relatif satu sama lain sehingga selalu terlihat, apa pun ukuran layar, rasio, kepadatannya.

Contoh cara memperbaikinya

Saya pribadi lebih memilih ConstraintLayout karena sangat kuat dalam hal positioning dan adaptasi.

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/loadbutton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Open Data File"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <firstapp.drawtwograph.Graph
        android:id="@+id/graph1"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        app:layout_constraintBottom_toTopOf="@+id/graph2"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/loadbutton" />

    <firstapp.drawtwograph.Graph
        android:id="@+id/graph2"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/graph1" />
</androidx.constraintlayout.widget.ConstraintLayout>

Hasilnya adalah (saya menggunakan dua tombol alih-alih tampilan Grafik):

Contoh solusi

Petunjuk:

  • Jika Anda ingin menggunakan ScrollView maka diperlukan pengaturan ketinggian tetap atau penentuan ketinggian saat waktu proses.
  • Singkirkan private final int zero = 700; // mark the 0 line of graph at 700 pixels. Jangan gunakan nilai piksel secara langsung karena akan menyebabkan UI rawan kesalahan. Ini akan menjadi kasus yang berfungsi di ponsel saya, tidak berfungsi di yang lain. Gunakan tinggi tampilan sebagai garis 0.
person Jenea Vranceanu    schedule 17.07.2020