Tambahkan beberapa tampilan dan kelas secara dinamis ke tampilan saat ini

Saya tertarik untuk mengisi layar/aktivitas dengan jumlah tampilan yang sama yang ditentukan pengguna. Setiap tampilan akan memiliki tata letak yang sama persis: beberapa TextView dan beberapa Tombol. Masalahnya adalah setiap tombol akan mengontrol apa yang akan ditampilkan oleh setiap TextView.

Cara saya berpikir untuk mengimplementasikannya adalah dengan memiliki satu XML dan satu kelas Java. Kemudian bergantung pada nomor yang dimasukkan pengguna, isi layar dengan banyak tampilan yang sama (menggunakan for loop). Pertanyaannya, apakah hal itu bisa dilakukan? Bagaimana? apakah aku memikirkannya dengan cara yang benar?

Tolong bantu dengan masukan atau pemikiran apa pun, contoh kode juga akan bagus.


person KingsInnerSoul    schedule 14.05.2013    source sumber
comment
Saya belum mencoba apa pun. Saya telah membaca tentang cara terbaik dan paling efisien untuk melakukannya. Saya telah melihat Fragmen, inflator, dan tampilan daftar. tetapi saya ingin membuatnya bereaksi terhadap penekanan tombol pada setiap tampilan tambahan yang terpisah. saya tidak dapat menemukan penjelasan yang terdokumentasi untuk itu.   -  person KingsInnerSoul    schedule 14.05.2013
comment
Anda harus menghapus pertanyaan Anda. Anda akan ditandai dan mendapat suara negatif.   -  person Siddharth    schedule 14.05.2013
comment
itu hal lain yang saya cari. bagaimana cara menghapus pertanyaan?   -  person KingsInnerSoul    schedule 14.05.2013
comment
Ada tombol hapus di bawah tag   -  person Siddharth    schedule 14.05.2013


Jawaban (2)


tentu saja bisa dilakukan.

Saya pikir yang paling mudah untuk situasi Anda, ditambah Anda dapat dengan mudah memperluasnya, adalah dengan membuat beberapa fungsi pembantu yang menangani:

1) membuat layar kosong 2) membuat tombol untuk layar 3) membuat tampilan teks untuk layar dan terakhir 4) membuat layar dan mengisinya

Anda harus memutuskan elemen Root yang tepat untuk Tampilan Anda, bergantung pada pengaturan anak yang Anda perlukan. Untuk mempermudah mari kita pilih LinearLayout, tetapi untuk RelativeLayout atau TableLayout contohnya sama, hanya saja ketika Anda menambahkan elemen, Anda harus menggunakan parameter tambahan untuk menempatkannya dengan benar.

Perhatikan bahwa fungsi untuk membuat tampilan kustom kosong mengembalikan ViewGroup ("tempat semua tata letak berasal"). Dengan cara ini, Anda selalu bekerja dengan ViewGroups dan cukup menentukan jenis tata letak layar satu kali, di dalam createCustomView. Jadi Anda dapat mengubah jenis layar di sana saja, dan kode lainnya akan berfungsi ...

Berikut ini beberapa kode untuk inspirasi Anda:

private ViewGroup createCustomView(Context context) {

    LinearLayout myCoolNewView=new LinearLayout(context); // or RelativeLayout, etc..
    return myCoolNewView;
} 

private Button createButton(Context context, String buttonText) {
    Button newButton=new Button(context);
    newButton.setText(buttonText);
    return newButton;
}

private TextView createText(Context context, String initialText) {
    TextView newText=new TextView(context);
    newText.setText(buttonText);
    return newText;
}

private ViewGroup createScreen(Context context, int numberOfButtons, int numberOfTextfields) {

    ViewGroup newScreen=createCustomView(context);
    TextView[] textViews=new TextView[numberOfTextFields];

    for (int i=0; i<numberOfTextfields; i++) {
          textViews[i]=createText(context, "hi i am text "+i);
           newScreen.addView(textViews[i]); // you ideally provide here layoutparams to properly place your buttons

    }
    for (int j=0; i<numberOfButtons; j++) {
          Button button=createButton(context, "hi i am button "+j);
          button.setOnClickListener(new OnClickListener() {
              public void onClick (View clickedView) {
                    // here you have a button keypress and you know all the textviews
                    textView[i%j].setText("hey you pressed me");
              }
          });
          newScreen.addView(button);
    }
    return newScreen;
}

Jadi sekarang Anda dapat:

ViewGroup screen1=createScreen(context, 10, 10);
ViewGroup screen2=createScreen(context, 5, 3);
ViewGroup screen3=createScreen(context, 2, 5);

dan menambahkan layar ke tata letak induk, ke ViewFlipper, ke ViewSwitcher, dll... seperti ini:

 ViewGroup parentLayoutOfAllScreens=findViewById(R.id.root_of_screens);
 parentLayoutOfAllScreens.addView(screen1);
 parentLayoutOfAllScreens.addView(screen2);
 parentLayoutOfAllScreens.addView(screen3);

Dalam XML Anda hanya perlu membuat tata letak root, dan beri nama root_of_screens...

pengkodean yang bagus!!! Saya kira akan ada beberapa kesalahan pada kode di atas, ketik saja di sini, tapi saya harap Anda mendapatkan idenya dan mengubahnya sesuai kebutuhan Anda!

EDIT : v2.0 : Memperluas Tampilan Buat .java baru bernama "MyCoolScreen.java" atau nama apa pun, di folder yang sama tempat aktivitas Anda (untuk mempermudah):

package ........
public class MyCoolScreen extends LinearLayout {

    /** Now every view holds its own buttons, and they are private, it's good for encapsulating */
    private TextView[] mTextViews; // <-- as a convention, members should start with "m"
    private Button[] mButtons;
    private UserPressedButtons mUserPressedButtonsListener; // See below

    /** The following constructors must always be present for a custom view, and must always call super */
    public MyCoolScreen(Context context) {
        // This is the constructor you will use when creating your view programmatically
        super(context);
    }

    public MyCoolScreen(Context context, AttributeSet attrs) {

        // This is the constructor Android calls when you include your custom view in an XML
        // You can do this too!! 
        // The ATTRS will then include your numberofbuttons and numberoftextfields from the XML
        // this is beyond the example, but read about it, it's interesting

        super(context, attrs); // this MUST ALWAYS be here for custom views, or they will not work.
                               // it tells the parent view to continue the construction.
    }

    public MyCoolScreen(Context context, AttributeSet attrs, int defStyle) {
        // Another constructor Android calls from the XML
        super(context, attrs, defStyle); 
    }


    /** We create an "init" method to initialize this view from outside */
    public void init(int numberOfTextViews, int numberOfButtons) {
        createScreen(numberOfTextViews, numberOfButtons);
    }


    /** This is the same */
    private Button createButton(Context context, String buttonText) {
        Button newButton=new Button(context);
        newButton.setText(buttonText);
        return newButton;
    }

    /** This is the same */
    private TextView createText(Context context, String initialText) {
        TextView newText=new TextView(context);
        newText.setText(buttonText);
        return newText;
    }

    /** We tweak this function so it doesnt return a view, but rather fills up this one :) */

    private void createScreen(int numberOfButtons, int numberOfTextfields) {

        ViewGroup newScreen=this; // It's this view the one we gonna fill up!
        mTextViews=new TextView[numberOfTextfields];
        mButtons=new Button[numberOfButtons];
        Context context=getContext(); // Views always know their context after constructed

        for (int i=0; i<numberOfTextfields; i++) {
              mTextViews[i]=createText(context, "hi i am text "+i);
              newScreen.addView(textViews[i]); // you ideally provide here layoutparams to properly place your buttons
        }

        for (int j=0; i<numberOfButtons; j++) {
              Button button=createButton(context, "hi i am button "+j);
              button.setId(j);
              button.setOnClickListener(new OnClickListener() {
                  public void onClick (View clickedView) {
                        // here you have a button keypress and you know all the textviews
                        if (mUserPressedButtonsListener!=null) mUserPressedButtonsListener.OnButtonPressed(j);
                        textView[i%j].setText("hey you pressed me");
                  }
              });
              mButtons[j]=button;
              newScreen.addView(button);
        }
    }

    public interface UserPressedButtons {
        public void OnButtonPressed(int buttonNumber);
    }

    public void setUserPressedButtonsListener (UserPressedButtons listener) {
         mUserPressedButtonsListener=listener;
    }
}

Oke, jadi sekarang untuk menggunakan ini, di Aktivitas Anda, Anda dapat melakukan:

    import ....... .MyCoolScreen;
    import ....... .MyCoolScreen.UserPressedButtons;

    .
    .
    .

    MyCoolScreen screen1=new MyCoolScreen(context);
    screen1.init(5,5); // initializes the screen.

    myRootLayout.addView(screen1);

Apa yang keren tentang ini, sekarang fungsionalitasnya sepenuhnya dikemas dalam tampilan kustom Anda. Dan itu berada di .java lain, sehingga kode aktivitas Anda sangat bersih, dan Anda bahkan dapat memperluas fungsionalitas Tampilan tanpa membuatnya jelek.

Ini juga merupakan praktik umum untuk membuat antarmuka dan pendengar bagi pandangan Anda untuk berkomunikasi dengan dunia luar, jadi misalnya, kita dapat melakukan:

     screen1.setUserPressedButtonsListener(new MyCoolScreen.UserPressedButtons() {
         @Override
         public void OnButtonPressed (int number) {
              // you know the user pressed button "number", and you can do stuff about it without
              // having to include it inside the MyCoolScreen class. Of course in your example you
              // don't need this at the moment, because the View will modify its textfield, but suppose
              // one of the buttons is "rocket launch" , that is something you will handle at the activity level, ie.

              if (number==ROCKET_LAUNCH) RocketLauncher.setTarget(10,10).launch(); // Your MyCoolScreen doesnt know how to launch rockets, but your activity maybe yes...

         }
     });

Anda dapat melakukan segala macam hal keren dengan tampilan kustom baru Anda. Misalnya, Anda dapat mendefinisikan:

     @Override
     public void OnDraw(Canvas c) {
          c.drawEllipse ...
          c.drawRectangle ....
     }

Dan Anda dapat melukis lingkaran, garis, dll... di atas bidang teks & tombol Anda :) Agar ini berfungsi, Anda harus meletakkannya

    setWillNotDraw(false) on the constructor.

Mungkin ada kesalahan, ketik saja kodenya di sini, tapi saya harap ini membantu Anda!

person rupps    schedule 14.05.2013
comment
Saya belum menguji kode ini, tapi sepertinya benar. Sama seperti apa yang saya pikirkan untuk dilakukan. Hal yang saya lewatkan, dan postingan Anda mengemukakan bahwa pemikiran untuk solusinya, adalah tentang menghasilkan ID unik untuk setiap elemen yang dibuat. Saya akan menambahkan kode Anda .setId(i); untuk setiap elemen yang ditambahkan. :-) Sudah larut malam, dan saya akan mengujinya besok dan akan membalasnya kembali. -Bersulang - person KingsInnerSoul; 14.05.2013
comment
noprob :) Tapi sekarang kamu tahu tentang setId, izinkan saya memberi tahu kamu tentang setTag(). Ini adalah sepupu yang lebih tua, sehingga Anda dapat menetapkan apa pun ke sebuah tombol, bukan hanya id. Anda dapat melakukan: view.setTag(my button), atau view.setTag(new String[]{button1,screen2}) atau bahkan view.setTag(new MyStuffInfo(a,b,c,d,e))) . ... dan kemudian lakukan view.getTag() untuk mendapatkannya :) - person rupps; 14.05.2013
comment
Ini berfungsi seperti pesona (setelah banyak memodifikasi kode Anda agar sesuai dengan pandangan yang saya inginkan). Sekarang saya mengalami masalah dengan id dan tag serta urutan elemen dalam LinearLayout. Tidak dapat menemukan cara yang tepat untuk memanggil kembali TextViews di tombol onClick untuk teh. - person KingsInnerSoul; 15.05.2013
comment
untuk masalah itu Anda dapat menyimpan semua bidang teks dalam larik pada tingkat layar, misalnya, lalu menetapkan sebagai ID tombol atau Menandai indeks larik bidang teks tersebut. Di OnClick Anda mendapatkan tampilan yang diklik sebagai parameter, sehingga id tombol akan menjadi indeks bidang teks. Ngomong-ngomong, cara pro adalah membuat kelas Screen yang memperluas LinearLayout, dengan logika untuk mengisinya di dalamnya, dan referensi ke bidang teks dan tombolnya sendiri. Dengan begitu setiap layar akan terpisah satu sama lain, dan masalah yang Anda hadapi akan lebih mudah diselesaikan. Beri tahu saya jika Anda memerlukan contoh kode tentang ini... - person rupps; 15.05.2013
comment
Jika saya memahami cara pro Anda - maka itulah cara yang ingin saya lakukan pada awalnya - tetapi tidak tahu caranya. Karena Layar Utama menampung semua tampilan - yang sama - saya berpikir untuk mengulangi tampilan yang sama, sebanyak yang ditentukan pengguna. Di situlah saya menemui jalan buntu dan solusi Anda berguna. Contoh kode akan sangat bagus, jika Anda bisa. - person KingsInnerSoul; 15.05.2013
comment
nah untuk memahami cara pro lebih baik pahami contoh pertama tadi, sekarang anda bisa melakukan refactor dengan benar! Lihat kode terlampir - person rupps; 15.05.2013

Menambah dan Menghapus Tampilan di Android Secara Dinamis?

ini akan sangat membantu Anda...

person Ramesh J    schedule 14.05.2013
comment
Saya sudah membacanya sebelumnya. Bukan itu yang saya cari. Saya ingin menambahkan beberapa tampilan secara dinamis - yang berasal dari satu tampilan - dan dapat mengontrol peristiwa untuk setiap tampilan secara mandiri. Peristiwa seperti mengubah TextViews dan ImageViews untuk setiap tampilan terpisah. - person KingsInnerSoul; 14.05.2013