Dinamik GUI ekleme

Ekran tasarımını content_main.xml den almak yerine mainActivity de yazdığımız kodla yapıyoruz.

Eğer Dinamik olarak oluşturulacaksa setContentView'e xmlden oluşturulmuş activity yerine yeni oluşturulan mainLayout verilir.

Her bir eleman bir üst parrent'a eklenir.

View elemanı eklerken yapılacaklar

  • nesne yarat parametre olarak this gecilir.
  • nesnenin parametrelerini gir
  • parrent layouta ekle.

MainLayout'u yaratırken yapılacaklar

  • nesne yarat ...Layout(this)
  • setTag(Utils.Counter) id ile islem yapilacaksa yazmiş olduğumuz Utils sınıfı R sınıfının yerine geçecektir.(Utils sınıfı yerine yani id ile uğraşmak istemiyorsak private veri elemanı olarak tutulabilir elemanlar.)
  • Utils.Views.put(Utils.Counter++, m_mainLayout) diyerek counter keyiyle Utils içindeki hashmap'e kaydet.
  • parametrelerini set et
  • orientation set et
  • this.setContentView(m_mainLayout) diyerek programın açılışta aradığı layoutu set et.

Örnek Kod :

Tasarım

  • MainLayout
    • InfoLayout
      • PlainText
      • EdıtText
    • ButtonsLayout
      • Button OK
      • Button Exit

Acıklama

EditText'e girilen yazı Tamam butonuyla Toast mesaja yazılacak. Exit Butonuyla programdan çıkış yapılacak.

  • Layoutlar private olarak yaratılır.
  • Her bir Layout için 2 init yazmak mantıklı
    • 1.de layout yaratılır ve parametreleri set edilir.
    • 2.de layouta eklenecek olan view elemanlar (child) eklenir.
  • setLayoutParams genişlik yükseklik vermek icin. ViewGroup.LayoutParams destekleyen sınıf ister
  • setOrientation ile Vertical verilir.
  • addView metoduyla layout içerisine View elemanı ekler.
  • onCreate'de setContentView metoduna mainLayout verilir.
  • EditTexte yazılan yazılar onSavedInstanceState ile kaydedilir onRestoreInstanceState ile geri alınır

MainActivity.java

package org.csystem.radiogroupsample;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity
{
    private LinearLayout m_mainLayout , m_infoLayout , m_buttonsLayout;
    private EditText m_editTextName ;

    private void init()
    {
        this.initMainLayout();
        this.initInfoLayout();
        this.initButtonsLayout();

        this.setContentView(m_mainLayout);
    }

    private void initMainLayout()
    {
        m_mainLayout = new LinearLayout(this);
        m_mainLayout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        m_mainLayout.setOrientation(LinearLayout.VERTICAL);
    }


    private void initInfoLayout()
    {
        m_infoLayout = new LinearLayout(this);
        m_infoLayout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT , ViewGroup.LayoutParams.WRAP_CONTENT));
        m_infoLayout.setOrientation(LinearLayout.HORIZONTAL);
        m_mainLayout.addView(m_infoLayout);
        this.initInfoLayoutViews();
    }

    private void initInfoLayoutViews()
    {
        TextView tv    = new TextView(this);
        tv.setText("Ad soyad");

        m_editTextName = new EditText(this);

        m_infoLayout.addView(tv);
        m_infoLayout.addView(m_editTextName);
    }


    private void initButtonsLayout()
    {
        m_buttonsLayout = new LinearLayout(this);
        m_buttonsLayout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        m_buttonsLayout.setOrientation(LinearLayout.HORIZONTAL);
        m_mainLayout.addView(m_buttonsLayout);
        this.initButtonsLayoutViews();
    }

    private void initButtonsLayoutViews()
    {
        Button button  = new Button(this);
        button.setText("Tamam");
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view)
            {
                Toast.makeText(getBaseContext(), m_editTextName.getText().toString(), Toast.LENGTH_SHORT).show();
            }
        });
        m_buttonsLayout.addView(button);

        button = new Button(this);
        button.setText("Cikis");
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view)
            {
                MainActivity.this.finish();
            }
        });
        m_buttonsLayout.addView(button);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        this.init();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState)
    {
        super.onSaveInstanceState(outState);
        outState.putString("EDITTEXT_NAME_TEXT" , m_editTextName.getText().toString());
    }


    @Override
    protected void onRestoreInstanceState(Bundle outState)
    {
        super.onSaveInstanceState(outState);
        m_editTextName.setText(outState.getString("EDITTEXT_NAME_TEXT"));
    }
}



View elemanlarını xmlden oluşturmadığımız için R sınıfı burada oluşturulmadı. Dolayısıyla dinamik olarak yaratılan View elemanlarının ID'si yoktur.ID ile yapılacak bi işlemimiz olsaydı Utils sınıfını kullanacaktık.

Utils.java

package csd.samples.buildprogrammatically;

import android.view.View;

import java.util.HashMap;

public class Utils {
    private Utils() {}
    public static HashMap<Integer, View> Views = new HashMap<>();
    public static int Counter = 1;
    public static  View findViewByTag(int tag)
    {
        View v = Views.get(tag);

        if (v == null)
            throw new IllegalArgumentException("Invalid tag");

        return v;
    }
}

MainActivity'de Kullanımı

int mainLayoutTag = Utils.Counter;
m_mainLayout.setTag(mainLayoutTag); //setTag ile View elemanına Utils.Counterden gelen idyi verdik
Utils.Views.put(Utils.Counter++, m_mainLayout); //Views hashmapine Counter'ı key olarak kullanarak elemanı ekledik

LinearLayout ly = (LinearLayout) Utils.findViewByTag(mainLayoutTag) //verilen id ye ait View elemanı geri döndürüldü.

Örnek Kod: Butona her basıldığında yeni bir editText ekleyen kod

  • Buton xml'den eklenir properties'den onClick metodu yazılır.
  • Butonlarin ekleneceği layout private eleman olarak tanımlanır ve findbyId ile atanır.
  • onClick içerisinde
    • Edittext nesnesi yaratılır.
    • Layouta addView ile eklenir.

Eklenen editTextler ekran döndürüldüğünde yok olacaktır.Kaybetmemek için

  • onSaveInstanceState
    • Önce EditTextlere girilen textler alınır
    • Kaç edittext olduğu counta alınır.
  • onRestoreInstanceState
    • Count kadar editText yaratılır
    • Textleri set edilir.

content_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="org.csystem.radiogroupsample.MainActivity"
    tools:showIn="@layout/activity_main"
    android:orientation="vertical">

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Ad - Soyad"
        android:id="@+id/editText"/>

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:id="@+id/MAINACTIVITY_LINEARLAYOUT_DYNAMIC">

        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="EKLE"
            android:onClick="addButtonClicked"/>
    </LinearLayout>

</LinearLayout>

mainActivity.java

package org.csystem.radiogroupsample;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.EditText;
import android.widget.LinearLayout;

public class MainActivity extends AppCompatActivity
{
    private LinearLayout m_layoutDynamic;
    private void init()
    {
        m_layoutDynamic =  (LinearLayout)this.findViewById(R.id.MAINACTIVITY_LINEARLAYOUT_DYNAMIC);
    }


    public  void addButtonClicked(View v)
    {
        EditText et = new EditText(this);
        et.setText("Telefon No");

        m_layoutDynamic.addView(et);
    }


    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        this.init();
    }


    @Override
    protected void onSaveInstanceState(Bundle outState)
    {
        super.onSaveInstanceState(outState);

        int count= m_layoutDynamic.getChildCount();
        int index = 0;
        for(int i=0 ; i< count ;i++)
        {
            View v = m_layoutDynamic.getChildAt(i);

            if( !(v instanceof EditText))
                continue;

            outState.putString("EDITTEXT" + index++ ,((EditText)v).getText().toString() );
        }
        outState.putInt("INDEX", index);
    }


    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState)
    {
        super.onSaveInstanceState(savedInstanceState);
        int count = savedInstanceState.getInt("INDEX");

        for(int i=0 ; i< count ;i++)
        {
            EditText et = new EditText(this);
            et.setText(savedInstanceState.getString("EDITTEXT"+i));
            m_layoutDynamic.addView(et);
        }
    }
}