Android'de nasıl özel bir klavye yapabilirsiniz?


105

Özel bir klavye yapmak istiyorum. XML ve Java kullanarak nasıl yapacağımı bilmiyorum. Aşağıdaki resim yapmak istediğim klavyenin bir modelidir. Sadece sayılara ihtiyacı var.

görüntü açıklamasını buraya girin


6
[Android Cihazlar için XML Düzenlerini Kullanarak Kendi Özel Klavyenizi Oluşturun] ( tutorials-android.blogspot.com/2011/06/… )
Jorgesys

1

Google'ın örnek bir "SoftKeyboard" projesi var veya burada bağlantılı oldukça fazla kaynak var: customkeyboarddetails.blogspot.com/2019/02/…
oliversisson

Yanıtlar:


83

Öncelikle keyboard.xml, res/xmlklasöre yerleştirilecek bir dosyaya ihtiyacınız olacak (klasör yoksa, onu oluşturdu).

<?xml version="1.0" encoding="utf-8"?> 
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
    android:keyWidth="15%p"
    android:keyHeight="15%p" >

    <Row>
        <Key android:codes="1"    android:keyLabel="1" android:horizontalGap="4%p"/>
        <Key android:codes="2"    android:keyLabel="2" android:horizontalGap="4%p"/>
        <Key android:codes="3"    android:keyLabel="3" android:horizontalGap="4%p" />
        <Key android:codes="4"    android:keyLabel="4" android:horizontalGap="4%p" />
        <Key android:codes="5"    android:keyLabel="5" android:horizontalGap="4%p" />
    </Row>
    <Row>
        <Key android:codes="6"    android:keyLabel="6" android:horizontalGap="4%p"/>
        <Key android:codes="7"    android:keyLabel="7" android:horizontalGap="4%p"/>
        <Key android:codes="8"    android:keyLabel="8" android:horizontalGap="4%p" />
        <Key android:codes="9"    android:keyLabel="9" android:horizontalGap="4%p" />
        <Key android:codes="0"    android:keyLabel="0" android:horizontalGap="4%p" />
    </Row>

    <Row>
        <Key android:codes="-1"    android:keyIcon="@drawable/backspace" android:keyWidth="34%p" android:horizontalGap="4%p"/>
        <Key android:codes="100"    android:keyLabel="Enter" android:keyWidth="53%p" android:horizontalGap="4%p"/>
    </Row>
 </Keyboard>

** backspaceÇekilebilir dosyayı oluşturmanız ve çok küçük boyutlu (18x18 piksel gibi) res / drawable-ldpi klasörüne yerleştirmeniz gerektiğini unutmayın.

Daha sonra kullanılmasını istediğiniz xml dosyasında (TextView'unuzun bulunduğu yerde) aşağıdaki kodu eklemelisiniz:

<RelativeLayout
 ...
>

        .....


        <android.inputmethodservice.KeyboardView
             android:id="@+id/keyboardview"
             android:layout_width="fill_parent"
             android:layout_height="wrap_content"
             android:layout_alignParentBottom="true"
             android:layout_centerHorizontal="true"
             android:focusable="true"
             android:focusableInTouchMode="true"
             android:visibility="gone" 
         />
         
        ......


</RelativeLayout>

** Eğer yerleştirir o xml dosyası olduğunu Not android.inputmethodservice.KeyboardViewin, olmak zorunda RelativeLayoutayarlamak edebilmek amacıylaalignParentBottom="true" (Genellikle klavyeler ekranın alt sunulmuştur)

Ardından , klavyeyi takmak istediğinizi işleyen onCreateişlevine aşağıdaki kodu eklemeniz gerekir .ActivityTextView

    // Create the Keyboard
    mKeyboard= new Keyboard(this,R.xml.keyboard);

    // Lookup the KeyboardView
    mKeyboardView= (KeyboardView)findViewById(R.id.keyboardview);
    // Attach the keyboard to the view
    mKeyboardView.setKeyboard( mKeyboard );
    
    // Do not show the preview balloons
    //mKeyboardView.setPreviewEnabled(false);
    
    // Install the key handler
    mKeyboardView.setOnKeyboardActionListener(mOnKeyboardActionListener);

** Not olduğunu mKeyboardve mKeyboardViewsen oluşturmak zorunda özel sınıf değişkenleri vardır.

Daha sonra klavyeyi açmak için aşağıdaki işleve ihtiyacınız vardır ( onClickxml özelliği aracılığıyla TextView ile ilişkilendirmeniz gerekir )

    public void openKeyboard(View v)
    {
       mKeyboardView.setVisibility(View.VISIBLE);
       mKeyboardView.setEnabled(true);
       if( v!=null)((InputMethodManager)getSystemService(Activity.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(v.getWindowToken(), 0);
    }

Ve nihayet OnKeyboardActionListenerolaylarınızı idare edecek olana ihtiyacınız var

private OnKeyboardActionListener mOnKeyboardActionListener = new OnKeyboardActionListener() {
    @Override public void onKey(int primaryCode, int[] keyCodes) 
    {
         //Here check the primaryCode to see which key is pressed 
         //based on the android:codes property
         if(primaryCode==1)
         {
            Log.i("Key","You just pressed 1 button");
         }
    }

    @Override public void onPress(int arg0) {
    }

    @Override public void onRelease(int primaryCode) {
    }

    @Override public void onText(CharSequence text) {
    }

    @Override public void swipeDown() {
    }

    @Override public void swipeLeft() {
    }

    @Override public void swipeRight() {
    }

    @Override public void swipeUp() {
    }
};

Umarım yardımcı olur!!!

Kodun çoğu burada bulundu

____________________________________________________________-

DÜZENLE:

KeyboardView, API seviyesi 29'dan beri amortismana tabi tutulduğundan, kodunu bu web sitesinde bulabilir ve klavyeyi yukarıda açıklandığı gibi uygulamadan önce kodunuzda bir sınıf oluşturabilirsiniz.


1
Ya klavyenin ekranın altında olmasını istemiyorsam? (örneğin, kullanıcının onu sürükleyebilmesini istiyorum). Bu, klavye uygulamamla kontrol edebileceğim bir şey mi yoksa android sistemi tarafından mı işleniyor?
user3294126

klavye genişliği ekranı doldurmuyor Tüm ekranları doldurması için ne yapmalıyım
George Thomas

KeyboardView’un içinde bulunduğu üst düzen nedir? Ayrıca KeyboardView’un layout_width değerini kontrol ettiniz mi?
Pontios

1
Lütfen KeyboardView ve Keyboard sınıflarının API seviyesi 29'dan beri Google tarafından kullanımdan kaldırıldığını unutmayın. Bu nedenle, daha yeni bir API seviyesini hedeflemeniz gerekirse bu çözüm gelecekte artık çalışmayacaktır.
maex

keyboardView, google tarafından kullanımdan kaldırıldı. yeni çözüm nedir?
tohidmahmoudvand

78

Sistem klavyesi

Bu cevap, bir kullanıcının telefonuna yüklediği herhangi bir uygulamada kullanılabilecek özel bir sistem klavyesinin nasıl yapılacağını anlatır. Yalnızca kendi uygulamanızda kullanılacak bir klavye yapmak istiyorsanız, diğer cevabımı görün .

Aşağıdaki örnek şöyle görünecektir. Herhangi bir klavye düzeni için değiştirebilirsiniz.

görüntü açıklamasını buraya girin

Aşağıdaki adımlar, çalışan bir özel sistem klavyesinin nasıl oluşturulacağını gösterir. Gereksiz kodları olabildiğince kaldırmaya çalıştım. İhtiyacınız olan başka özellikler varsa, sonunda daha fazla yardım için bağlantılar verdim.

1. Yeni bir Android projesi başlatın

Projeme "Özel Klavye" adını verdim. Ne istersen söyle. Burada özel bir şey yok. Sadece terk edeceğimMainActivity ve "Merhaba Dünya!" düzen olduğu gibi.

2. Düzen dosyalarını ekleyin

Aşağıdaki iki dosyayı uygulamanızın res/layoutklasörüne ekleyin :

  • keyboard_view.xml
  • key_preview.xml

keyboard_view.xml

Bu görünüm, klavyemizi tutacak bir kap gibidir. Bu örnekte yalnızca bir klavye vardır, ancak başka klavyeler ekleyebilir ve bunların içine girip çıkabilirsiniz KeyboardView.

<?xml version="1.0" encoding="utf-8"?>
<android.inputmethodservice.KeyboardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/keyboard_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:keyPreviewLayout="@layout/key_preview"
    android:layout_alignParentBottom="true">

</android.inputmethodservice.KeyboardView>

key_preview.xml

Tuş önizlemesi, bir klavye tuşuna bastığınızda açılan bir düzendir. Sadece hangi tuşa bastığınızı gösterir (büyük, şişman parmaklarınız onu kapatıyorsa). Bu çoktan seçmeli bir pop-up değil. Bunun için Adaylar görünümüne bakmalısınız .

<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:background="@android:color/white"
    android:textColor="@android:color/black"
    android:textSize="30sp">
</TextView>

3. Destekleyici xml dosyalarını ekleyin

xmlKlasörünüzde bir klasör oluşturun res. (Sağ tıklayın resve Yeni> Dizin'i seçin .)

Ardından aşağıdaki iki xml dosyasını buna ekleyin. ( xmlKlasöre sağ tıklayın ve Yeni> XML kaynak dosyası'nı seçin .)

  • number_pad.xml
  • method.xml

number_pad.xml

Daha ilginç olmaya başladığı yer burasıdır. Bu Keyboard, tuşların düzenini tanımlar .

<?xml version="1.0" encoding="utf-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
    android:keyWidth="20%p"
    android:horizontalGap="5dp"
    android:verticalGap="5dp"
    android:keyHeight="60dp">

    <Row>
        <Key android:codes="49" android:keyLabel="1" android:keyEdgeFlags="left"/>
        <Key android:codes="50" android:keyLabel="2"/>
        <Key android:codes="51" android:keyLabel="3"/>
        <Key android:codes="52" android:keyLabel="4"/>
        <Key android:codes="53" android:keyLabel="5" android:keyEdgeFlags="right"/>
    </Row>

    <Row>
        <Key android:codes="54" android:keyLabel="6" android:keyEdgeFlags="left"/>
        <Key android:codes="55" android:keyLabel="7"/>
        <Key android:codes="56" android:keyLabel="8"/>
        <Key android:codes="57" android:keyLabel="9"/>
        <Key android:codes="48" android:keyLabel="0" android:keyEdgeFlags="right"/>
    </Row>

    <Row>
        <Key android:codes="-5"
             android:keyLabel="DELETE"
             android:keyWidth="40%p"
             android:keyEdgeFlags="left"
             android:isRepeatable="true"/>
        <Key android:codes="10"
             android:keyLabel="ENTER"
             android:keyWidth="60%p"
             android:keyEdgeFlags="right"/>
    </Row>

</Keyboard>

Dikkat etmeniz gereken bazı noktalar şunlardır:

  • keyWidth: Bu, her tuşun varsayılan genişliğidir. 20%pVasıtası, her anahtar genişliğinin% 20 kadar sürer s değiller. Üçüncü satırdaki Sil ve Gir tuşlarıyla gerçekleştiğini görebileceğiniz gibi, tek tek tuşlarla geçersiz kılınabilir.
  • keyHeight: Burada kodlanmıştır, ancak @dimen/key_heightfarklı ekran boyutları için dinamik olarak ayarlamak gibi bir şey kullanabilirsiniz .
  • Gap: Yatay ve dikey boşluk, tuşlar arasında ne kadar boşluk bırakılacağını belirtir. Ayarlasanız bile 0pxküçük bir boşluk var.
  • codes: Bu, ne olacağını veya tuşa basıldığında neyin girileceğini belirleyen bir Unicode veya özel kod değeri olabilir. Daha keyOutputTextuzun bir Unicode dizesi girmek isteyip istemediğinize bakın .
  • keyLabel: Bu, tuşta görüntülenen metindir.
  • keyEdgeFlags: Bu, tuşun hangi kenara hizalanması gerektiğini gösterir.
  • isRepeatable: Tuşa basılı tutarsanız, girişi tekrar etmeye devam edecektir.

method.xml

Bu dosya, sisteme mevcut giriş yöntemi alt türlerini söyler. Buraya sadece minimal bir versiyon ekliyorum.

<?xml version="1.0" encoding="utf-8"?>
<input-method
    xmlns:android="http://schemas.android.com/apk/res/android">

    <subtype
        android:imeSubtypeMode="keyboard"/>

</input-method>

4. Anahtar girişini işlemek için Java kodunu ekleyin

Yeni bir Java dosyası oluşturun. Hadi diyelim MyInputMethodService. Bu dosya her şeyi birbirine bağlar. Klavyeden alınan girdiyi işler ve onu aldığı görünüme gönderir ( EditTextörneğin).

public class MyInputMethodService extends InputMethodService implements KeyboardView.OnKeyboardActionListener {

    @Override
    public View onCreateInputView() {
        // get the KeyboardView and add our Keyboard layout to it
        KeyboardView keyboardView = (KeyboardView) getLayoutInflater().inflate(R.layout.keyboard_view, null);
        Keyboard keyboard = new Keyboard(this, R.xml.number_pad);
        keyboardView.setKeyboard(keyboard);
        keyboardView.setOnKeyboardActionListener(this);
        return keyboardView;
    }

    @Override
    public void onKey(int primaryCode, int[] keyCodes) {

        InputConnection ic = getCurrentInputConnection();
        if (ic == null) return;
        switch (primaryCode) {
            case Keyboard.KEYCODE_DELETE:
                CharSequence selectedText = ic.getSelectedText(0);
                if (TextUtils.isEmpty(selectedText)) {
                    // no selection, so delete previous character
                    ic.deleteSurroundingText(1, 0);
                } else {
                    // delete the selection
                    ic.commitText("", 1);
                }
                break;
            default:
                char code = (char) primaryCode;
                ic.commitText(String.valueOf(code), 1);
        }
    }

    @Override
    public void onPress(int primaryCode) { }

    @Override
    public void onRelease(int primaryCode) { }

    @Override
    public void onText(CharSequence text) { }

    @Override
    public void swipeLeft() { }

    @Override
    public void swipeRight() { }

    @Override
    public void swipeDown() { }

    @Override
    public void swipeUp() { }
}

Notlar:

  • OnKeyboardActionListenerKlavye girişi için dinlemektedir. Ayrıca bu örnekteki tüm bu boş yöntemleri gerektirir.
  • InputConnectionBir gibi başka görünüme girdi göndermek için kullanılan budur EditText.

5. Manifest'i güncelleyin

Bunu ilk yerine son olarak koydum çünkü yukarıda zaten eklediğimiz dosyalara atıfta bulunuyor. Özel klavyenizi bir sistem klavyesi olarak kaydetmek serviceiçin AndroidManifest.xml dosyanıza bir bölüm eklemeniz gerekir . Sonraki applicationbölüme koyun activity.

<manifest ...>
    <application ... >
        <activity ... >
            ...
        </activity>

        <service
            android:name=".MyInputMethodService"
            android:label="Keyboard Display Name"
            android:permission="android.permission.BIND_INPUT_METHOD">
            <intent-filter>
                <action android:name="android.view.InputMethod"/>
            </intent-filter>
            <meta-data
                android:name="android.view.im"
                android:resource="@xml/method"/>
        </service>

    </application>
</manifest>

Bu kadar! Şimdi uygulamanızı çalıştırabilmelisiniz. Ancak, klavyenizi ayarlarda etkinleştirene kadar pek bir şey görmeyeceksiniz.

6. Klavyeyi Ayarlar'da etkinleştirin

Klavyenizi kullanmak isteyen her kullanıcının Android ayarlarında onu etkinleştirmesi gerekecektir. Bunun nasıl yapılacağına ilişkin ayrıntılı talimatlar için aşağıdaki bağlantıya bakın:

İşte özet:

  • Android Ayarları> Diller ve giriş> Geçerli klavye> Klavye seç'e gidin.
  • Özel Klavyenizi listede görmelisiniz. Onu etkinleştir.
  • Geri dönün ve tekrar Mevcut klavye'yi seçin. Özel Klavyenizi listede görmelisiniz. Onu seç.

Artık klavyenizi Android'de yazabileceğiniz her yerde kullanabilmelisiniz.

İlerideki çalışma

Yukarıdaki klavye kullanılabilir, ancak başkalarının kullanmak isteyeceği bir klavye oluşturmak için muhtemelen daha fazla işlevsellik eklemeniz gerekecektir. Nasıl yapılacağını öğrenmek için aşağıdaki bağlantıları inceleyin.

Devam Ediyor

Standardın KeyboardViewgörünüşü ve davranışı hoşunuza gitmiyor mu? Ben kesinlikle yapmıyorum. Görünüşe göre Android 2.0'dan beri güncellenmemiş. Play Store'daki tüm bu özel klavyelere ne dersiniz? Yukarıdaki çirkin klavyeye hiç benzemiyorlar.

İyi haber şu ki, kendi klavyenizin görünümünü ve davranışını tamamen özelleştirebilirsiniz. Aşağıdakileri yapmanız gerekecek:

  1. Alt sınıflar oluşturan kendi özel klavye görünümünüzü oluşturun ViewGroup. Bunu Buttons ile doldurabilir veya alt sınıfa ait kendi özel anahtar görünümlerinizi bile oluşturabilirsiniz View. Açılır görünümler kullanıyorsanız, bunu not edin .
  2. Bir ekleme özel etkinlik dinleyici sizin klavyede arayüz. onKeyClicked(String text)Veya gibi şeyler için yöntemlerini çağırın onBackspace().
  3. Ekleyebilir gerek yok keyboard_view.xml, key_preview.xmlya number_pad.xmlbu standart için tüm olduklarından yukarıda yönlerde açıklandığı KeyboardView. Tüm bu UI yönlerini özel görünümünüzde ele alacaksınız.
  4. Senin içinde MyInputMethodServicesınıfa, klavye sınıfında tanımlanan söz konusu özel klavye dinleyici uygulamak. Bu, yerinde olduğundan KeyboardView.OnKeyboardActionListenerartık ihtiyaç olan,.
  5. Sizin de MyInputMethodServicesınıfının onCreateInputView()yöntemi oluşturmak ve özel klavyenin bir örneğini döndürür. Klavyenin özel dinleyicisini olarak ayarlamayı unutmayın this.

35

Uygulama İçi Klavye

Bu cevap, yalnızca uygulamanızın içinde kullanmak için özel bir klavyenin nasıl yapılacağını anlatır. Herhangi bir uygulamada kullanılabilecek bir sistem klavyesi yapmak istiyorsanız, diğer cevabıma bakın .

Örnek şöyle görünecek. Herhangi bir klavye düzeni için değiştirebilirsiniz.

görüntü açıklamasını buraya girin

1. Yeni bir Android projesi başlatın

Projeme isim verdim InAppKeyboard. Sen ne istersen onu ara.

2. Düzen dosyalarını ekleyin

Klavye düzeni

res/layoutKlasöre bir düzen dosyası ekleyin . Benimkini aradım keyboard. Klavye, bu xml düzen dosyasından şişireceğimiz özel bir bileşik görünüm olacaktır. Anahtarları düzenlemek için istediğiniz düzeni kullanabilirsiniz, ancak ben bir LinearLayout. mergeEtiketleri not edin .

res / layout / keyboard.xml

<merge xmlns:android="http://schemas.android.com/apk/res/android">

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

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

            <Button
                android:id="@+id/button_1"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="1"/>

            <Button
                android:id="@+id/button_2"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="2"/>

            <Button
                android:id="@+id/button_3"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="3"/>

            <Button
                android:id="@+id/button_4"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="4"/>

            <Button
                android:id="@+id/button_5"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="5"/>

        </LinearLayout>

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

            <Button
                android:id="@+id/button_6"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="6"/>

            <Button
                android:id="@+id/button_7"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="7"/>

            <Button
                android:id="@+id/button_8"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="8"/>

            <Button
                android:id="@+id/button_9"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="9"/>

            <Button
                android:id="@+id/button_0"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="0"/>

        </LinearLayout>

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

            <Button
                android:id="@+id/button_delete"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="2"
                android:text="Delete"/>

            <Button
                android:id="@+id/button_enter"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="3"
                android:text="Enter"/>

        </LinearLayout>
    </LinearLayout>

</merge>

Aktivite düzeni

Gösteri amacıyla, faaliyetimizin bir tekli vardır EditTextve klavye alt kısımdadır. Özel klavye görünümümü aradım MyKeyboard. (Bu kodu yakında ekleyeceğiz, bu nedenle hatayı şimdilik görmezden gelin.) Tüm klavye kodumuzu tek bir görünüme koymanın yararı, başka bir etkinlik veya uygulamada yeniden kullanılmasını kolaylaştırmasıdır.

res / layout / activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.inappkeyboard.MainActivity">

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#c9c9f1"
        android:layout_margin="50dp"
        android:padding="5dp"
        android:layout_alignParentTop="true"/>

    <com.example.inappkeyboard.MyKeyboard
        android:id="@+id/keyboard"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_alignParentBottom="true"/>

</RelativeLayout>

3. Klavye Java dosyasını ekleyin

Yeni bir Java dosyası ekleyin. Benimkini aradım MyKeyboard.

Burada dikkat edilmesi gereken en önemli şey, herhangi bir EditTextveya Activity. Bu, onu ihtiyaç duyan herhangi bir uygulama veya etkinliğe bağlamayı kolaylaştırır. Bu özel klavye görünümü ayrıca, bir InputConnectionsistem klavyesinin bir EditText. Sabit bağlantılardan bu şekilde kaçınıyoruz.

MyKeyboard yukarıda tanımladığımız görünüm düzenini şişiren bileşik bir görünümdür.

MyKeyboard.java

public class MyKeyboard extends LinearLayout implements View.OnClickListener {

    // constructors
    public MyKeyboard(Context context) {
        this(context, null, 0);
    }

    public MyKeyboard(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyKeyboard(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    // keyboard keys (buttons)
    private Button mButton1;
    private Button mButton2;
    private Button mButton3;
    private Button mButton4;
    private Button mButton5;
    private Button mButton6;
    private Button mButton7;
    private Button mButton8;
    private Button mButton9;
    private Button mButton0;
    private Button mButtonDelete;
    private Button mButtonEnter;

    // This will map the button resource id to the String value that we want to 
    // input when that button is clicked.
    SparseArray<String> keyValues = new SparseArray<>();

    // Our communication link to the EditText
    InputConnection inputConnection;

    private void init(Context context, AttributeSet attrs) {

        // initialize buttons
        LayoutInflater.from(context).inflate(R.layout.keyboard, this, true);
        mButton1 = (Button) findViewById(R.id.button_1);
        mButton2 = (Button) findViewById(R.id.button_2);
        mButton3 = (Button) findViewById(R.id.button_3);
        mButton4 = (Button) findViewById(R.id.button_4);
        mButton5 = (Button) findViewById(R.id.button_5);
        mButton6 = (Button) findViewById(R.id.button_6);
        mButton7 = (Button) findViewById(R.id.button_7);
        mButton8 = (Button) findViewById(R.id.button_8);
        mButton9 = (Button) findViewById(R.id.button_9);
        mButton0 = (Button) findViewById(R.id.button_0);
        mButtonDelete = (Button) findViewById(R.id.button_delete);
        mButtonEnter = (Button) findViewById(R.id.button_enter);

        // set button click listeners
        mButton1.setOnClickListener(this);
        mButton2.setOnClickListener(this);
        mButton3.setOnClickListener(this);
        mButton4.setOnClickListener(this);
        mButton5.setOnClickListener(this);
        mButton6.setOnClickListener(this);
        mButton7.setOnClickListener(this);
        mButton8.setOnClickListener(this);
        mButton9.setOnClickListener(this);
        mButton0.setOnClickListener(this);
        mButtonDelete.setOnClickListener(this);
        mButtonEnter.setOnClickListener(this);

        // map buttons IDs to input strings
        keyValues.put(R.id.button_1, "1");
        keyValues.put(R.id.button_2, "2");
        keyValues.put(R.id.button_3, "3");
        keyValues.put(R.id.button_4, "4");
        keyValues.put(R.id.button_5, "5");
        keyValues.put(R.id.button_6, "6");
        keyValues.put(R.id.button_7, "7");
        keyValues.put(R.id.button_8, "8");
        keyValues.put(R.id.button_9, "9");
        keyValues.put(R.id.button_0, "0");
        keyValues.put(R.id.button_enter, "\n");
    }

    @Override
    public void onClick(View v) {

        // do nothing if the InputConnection has not been set yet
        if (inputConnection == null) return;

        // Delete text or input key value
        // All communication goes through the InputConnection
        if (v.getId() == R.id.button_delete) {
            CharSequence selectedText = inputConnection.getSelectedText(0);
            if (TextUtils.isEmpty(selectedText)) {
                // no selection, so delete previous character
                inputConnection.deleteSurroundingText(1, 0);
            } else {
                // delete the selection
                inputConnection.commitText("", 1);
            }
        } else {
            String value = keyValues.get(v.getId());
            inputConnection.commitText(value, 1);
        }
    }

    // The activity (or some parent or controller) must give us 
    // a reference to the current EditText's InputConnection
    public void setInputConnection(InputConnection ic) {
        this.inputConnection = ic;
    }
}

4. Klavyeyi Metni Düzenle seçeneğine çevirin

Sistem klavyeleri için Android , klavyeyi odaklanılana yönlendirmek için bir InputMethodManager kullanır EditText. Bu örnekte, etkinlik, 'den EditTextözel klavyemize bağlantı sağlayarak yerini alacaktır .

Sistem klavyesini kullanmadığımız için EditText,. İkincisi, ' InputConnectiondan almalı EditTextve klavyemize vermeliyiz.

MainActivity.java

public class MainActivity extends AppCompatActivity {

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

        EditText editText = (EditText) findViewById(R.id.editText);
        MyKeyboard keyboard = (MyKeyboard) findViewById(R.id.keyboard);

        // prevent system keyboard from appearing when EditText is tapped
        editText.setRawInputType(InputType.TYPE_CLASS_TEXT);
        editText.setTextIsSelectable(true);

        // pass the InputConnection from the EditText to the keyboard
        InputConnection ic = editText.onCreateInputConnection(new EditorInfo());
        keyboard.setInputConnection(ic);
    }
}

Aktivitenizde birden fazla EditTexts varsa, doğru EditText'leri klavyeye geçirmek için kod yazmanız gerekecektir InputConnection. (Bunu EditTexts'e bir OnFocusChangeListenerve ekleyerek OnClickListeneryapabilirsiniz. Bununla ilgili tartışma için bu makaleye bakın .) Klavyenizi uygun zamanlarda gizlemek veya göstermek de isteyebilirsiniz.

Bitti

Bu kadar. Örnek uygulamayı şimdi çalıştırabilmeli ve istediğiniz şekilde metin girebilmeli veya silebilmelisiniz. Bir sonraki adımınız, her şeyi kendi ihtiyaçlarınıza uyacak şekilde değiştirmektir. Örneğin, bazı klavyelerimde Buttons yerine TextView'i kullandım çünkü onları özelleştirmek daha kolay.

Notlar

  • Xml düzen dosyasında, anahtarların daha iyi görünmesini istiyorsanız, bir TextViewyerine a da kullanabilirsiniz Button. Ardından, arka planı, basıldığında görünüm durumunu değiştiren bir çekilebilir yapın.
  • Gelişmiş özel klavyeler: Klavye görünümünde ve klavye değiştirmede daha fazla esneklik için, şimdi alt sınıflara ayıran özel tuş görünümleri ve alt sınıflar oluşturan Viewözel klavyeler yapıyorum ViewGroup. Klavye, tüm tuşları programlı olarak düzenler. Tuşlar, klavye ile iletişim kurmak için bir arabirim kullanır (parçaların bir etkinlikle nasıl iletişim kurduğuna benzer). Xml düzeni bunun için iyi çalıştığından, yalnızca tek bir klavye düzenine ihtiyacınız varsa bu gerekli değildir. Ancak üzerinde çalıştığım şeyin bir örneğini görmek isterseniz, buradaki tüm Key*ve Keyboard*sınıflara göz atın . Ayrıca, işlevi klavyeleri içeri ve dışarı değiştirmek olan bir konteyner görünümü kullandığımı da unutmayın.

Cevabınız harika, ancak orijinal klavye ile bu yeni klavye arasında geçiş yapmayı nasıl ayarlayabiliriz?
Kishan Donga

@KishanDonga, Klavyenizde klavyeler arasında geçiş yapmak için bir tuş ekleyebilirsiniz. Kullanıcı bastığında arayın InputMethodManager#showInputMethodPicker(). Orijinal klavyede böyle bir tuş yoksa, kullanıcıların klavyenize geçebilmesinin tek yolu, bunu sistem ayarlarında manuel olarak yapmaktır. Apple, bu alanda Android'den daha üstündür çünkü Apple, tüm klavyelerin bir klavye geçiş anahtarına sahip olmasını gerektirir.
Suragch

@KishanDonga, bu cevabın sistem klavyesi değil, uygulama içi klavye ile ilgili olduğunu fark ettim. İki özel klavye arasında geçiş yapmak istiyorsanız, bunları programlı olarak bir kapsayıcı görünümünün içine ve dışına değiştirebilirsiniz. Her iki klavyeye de bir takas klavye tuşu eklemeniz yeterlidir. "Gelişmiş özel klavyeler" notuma bakın ve yukarıdaki yanıta bağlantı verin.
Suragch

Klavyeniz ve sistem klavyesi arasında geçiş yapmak istiyorsanız, sistem klavyesini gizleyin ve uygun zamanlarda klavyenizi gösterin (veya tersi).
Suragch

1
@MarekTakac, sistem klavyesini devre dışı bırakmanız ve her aktivitede özel klavyenizi eklemeniz gerekecek. Bir etkinliğin birden çok URL'si varsa, odak aldıklarında mevcut klavyeden özel klavyenize atayabilmeniz için bunlara EditTextbir eklemeniz gerekir . onFocusChangedListenerInputConnectionEditText
Suragch

31

Kullanım KeyboardView:

KeyboardView kbd = new KeyboardView(context);
kbd.setKeyboard(new Keyboard(this, R.xml.custom));

kbd.setOnKeyboardActionListener(new OnKeyboardActionListener() {
    ....
}

şimdi kbdnormal bir görüşe sahipsiniz .

Bunun güzel yanı , xml'de klavyenin düzenini tanımlayan R.xml.customanlamına gelir /res/xml/custom.xml. Bu dosya hakkında daha fazla bilgi için şuraya bakın: Keyboard , Keyboard.Row , Keyboard.Key .


2
KeyboardView sınıfını kullanıyorum, ancak API 29 itibariyle artık kullanımdan kaldırıldı.
Abhijit

14

Burada yazılım klavyesi için örnek bir proje yer almaktadır.

https://developer.android.com/guide/topics/text/creating-input-method.html

Sizinki farklı bir düzende aynı satırda olmalıdır.

Düzenleme: Klavyeye yalnızca uygulamanızda ihtiyacınız varsa, çok basit! Dikey yönlendirmeli doğrusal bir düzen oluşturun ve içinde yatay yönlendirmeyle 3 doğrusal düzen oluşturun. Daha sonra her satırın düğmelerini bu yatay doğrusal düzenlerin her birine yerleştirin ve ağırlık özelliğini düğmelere atayın. Hepsi için android: layout_weight = 1 kullanın, böylece eşit aralıklar elde ederler.

Bu çözecektir. Bekleneni almadıysanız, lütfen kodu buraya gönderin, size yardımcı olmak için buradayız!


Düzenleme aslında kötü çünkü bu, klavyenin her zaman gösterildiği ve stok Android klavyesi gibi davranmayacağı anlamına gelir.
m0skit0


4

Kendi özel klavyemi oluşturmak için hangi yöntemi kullanacağıma karar vermeye çalışırken geçenlerde bu yazıya rastladım. Android sistem API'sini çok sınırlı buldum, bu yüzden kendi uygulama içi klavyemi yapmaya karar verdim. Suragch'ın cevabını araştırmamın temeli olarak kullanarak kendi klavye bileşenimi tasarlamaya başladım . MIT lisansıyla GitHub'da yayınlanmıştır. Umarım bu, başkalarına çok zaman kazandırır ve baş ağrısını azaltır.

Mimari oldukça esnektir. İstediğiniz klavye düzeni ve denetleyiciyle enjekte edebileceğiniz bir ana görünüm (CustomKeyboardView) vardır.

Sadece xml etkinliğinizde CustomKeyboardView'ı beyan etmeniz gerekir (bunu programlı olarak da yapabilirsiniz):

    <com.donbrody.customkeyboard.components.keyboard.CustomKeyboardView
    android:id="@+id/customKeyboardView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true" />

Ardından EditText'lerinizi kaydedin ve ona ne tür klavye kullanmaları gerektiğini söyleyin:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val numberField: EditText = findViewById(R.id.testNumberField)
    val numberDecimalField: EditText = findViewById(R.id.testNumberDecimalField)
    val qwertyField: EditText = findViewById(R.id.testQwertyField)

    keyboard = findViewById(R.id.customKeyboardView)
    keyboard.registerEditText(CustomKeyboardView.KeyboardType.NUMBER, numberField)
    keyboard.registerEditText(CustomKeyboardView.KeyboardType.NUMBER_DECIMAL, numberDecimalField)
    keyboard.registerEditText(CustomKeyboardView.KeyboardType.QWERTY, qwertyField)
}

CustomKeyboardView gerisini halleder!

Topu bir Number, NumberDecimal ve QWERTY klavyeyle yuvarladım. İndirmekten ve kendi düzenlerinizi ve kontrol cihazlarınızı oluşturmaktan çekinmeyin. Şöyle görünüyor:

android özel klavye gif manzara

görüntü açıklamasını buraya girin

Kullanmaya karar verdiğiniz mimari bu olmasa bile, umarım çalışan bir uygulama içi klavyenin kaynak kodunu görmeniz yararlı olacaktır.

Yine, işte projenin bağlantısı: Özel Uygulama İçi Klavye


2

Suragch şimdiye kadarki en iyi cevabı verdi, ancak uygulamanın derlenmesi için önemli olan bazı küçük şeyleri atladı.

Cevabını geliştirerek Suragch'ten daha iyi bir cevap vermeyi umuyorum. Onun koymadığı tüm eksik unsurları ekleyeceğim.

APK'mı android uygulaması APK Builder 1.1.0'ı kullanarak derledim. Öyleyse başlayalım.

Bir Android uygulaması oluşturmak için, belirli bir biçimde düzenlenmiş ve buna göre büyük harfle yazılmış birkaç dosya ve klasöre ihtiyacımız var.

res layout -> uygulamanın telefonda nasıl görüneceğini gösteren xml dosyaları. HTML'nin web sayfasının tarayıcıda nasıl göründüğünü şekillendirmesine benzer. Uygulamanızın uygun şekilde ekranlara sığmasına izin verme.

değerler -> colours.xml, strings.xml, styles.xml gibi sabit veriler. Bu dosyalar düzgün yazılmalıdır.

çizilebilir -> resimler {jpeg, png, ...}; Onlara herhangi bir isim verin.

mipmap -> daha fazla resim. uygulama simgesi için mi kullanılır?

xml -> daha fazla xml dosyası.

src -> html'de JavaScript gibi davranır. düzen dosyaları başlangıç ​​görünümünü başlatır ve java dosyanız etiket öğelerini dinamik olarak kontrol eder ve olayları tetikler. Olaylar, html'de olduğu gibi doğrudan layout.xml'de de etkinleştirilebilir.

AndroidManifest.xml -> Bu dosya, uygulamanızın ne hakkında olduğunu kaydeder. Uygulama adı, Program türü, gerekli izinler, vb. Bu, Android'i oldukça güvenli kılıyor gibi görünüyor. Programlar Manifest'te istemediklerini tam anlamıyla yapamazlar.

Artık 4 tür Android programı, bir etkinlik, bir hizmet, bir içerik sağlayıcı ve bir yayın alıcısı var. Klavyemiz arka planda çalışmasına izin veren bir hizmet olacaktır. Başlatılacak uygulamalar listesinde görünmez; ancak kaldırılabilir.

Uygulamanızı derlemek için gradle ve apk imzalamayı içerir. Bunu araştırabilir veya android için APK Builder'ı kullanabilirsiniz. Bu çok kolay.

Artık Android geliştirmeyi anladığımıza göre, dosya ve klasörleri oluşturalım.

  1. Yukarıda bahsettiğim gibi dosya ve klasörleri oluşturun. Rehberim aşağıdaki gibi görünecek:

    • NumPad
      • AndroidManifest.xml
      • src
        • Saragch
          • num_pad
            • MyInputMethodService.java
      • res
        • çekilebilir
          • Suragch_NumPad_icon.png
        • Yerleşim
          • key_preview.xml
          • keyboard_view.xml
        • xml
          • method.xml
          • number_pad.xml
        • değerler
          • colours.xml
          • strings.xml
          • styles.xml

Android Studio gibi bir ide kullanıyorsanız, bir proje dosyası olabileceğini unutmayın.

  1. Dosyaları yazın.

A: NumPad / res / layout / key_preview.xml

<?xml version="1.0" encoding="utf-8"?>
   <TextView
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:gravity="center"
      android:background="@android:color/white"
      android:textColor="@android:color/black"
      android:textSize="30sp">
</TextView>

B: NumPad / res / layout / keyboard_view.xml

<?xml version="1.0" encoding="utf-8"?>
<android.inputmethodservice.KeyboardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/keyboard_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:keyPreviewLayout="@layout/key_preview"
    android:layout_alignParentBottom="true">

</android.inputmethodservice.KeyboardView>

C: NumPad / res / xml / method.xml

<?xml version="1.0" encoding="utf-8"?>
<input-method  xmlns:android="http://schemas.android.com/apk/res/android">
    <subtype  android:imeSubtypeMode="keyboard"/>
</input-method>

D: Numpad / res / xml / number_pad.xml

<?xml version="1.0" encoding="utf-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
    android:keyWidth="20%p"
    android:horizontalGap="5dp"
    android:verticalGap="5dp"
    android:keyHeight="60dp">

    <Row>
        <Key android:codes="49" android:keyLabel="1" android:keyEdgeFlags="left"/>
        <Key android:codes="50" android:keyLabel="2"/>
        <Key android:codes="51" android:keyLabel="3"/>
        <Key android:codes="52" android:keyLabel="4"/>
        <Key android:codes="53" android:keyLabel="5" android:keyEdgeFlags="right"/>
    </Row>

    <Row>
        <Key android:codes="54" android:keyLabel="6" android:keyEdgeFlags="left"/>
        <Key android:codes="55" android:keyLabel="7"/>
        <Key android:codes="56" android:keyLabel="8"/>
        <Key android:codes="57" android:keyLabel="9"/>
        <Key android:codes="48" android:keyLabel="0" android:keyEdgeFlags="right"/>
    </Row>

    <Row>
        <Key android:codes="-5"
             android:keyLabel="DELETE"
             android:keyWidth="40%p"
             android:keyEdgeFlags="left"
             android:isRepeatable="true"/>
        <Key android:codes="10"
             android:keyLabel="ENTER"
             android:keyWidth="60%p"
             android:keyEdgeFlags="right"/>
    </Row>

</Keyboard>

Elbette bu, beğeninize göre kolayca düzenlenebilir. Etiket için kelimeler yerine resimleri bile kullanabilirsiniz.

Suragch değerler klasöründeki dosyaları göstermedi ve Android Studio'ya erişimimiz olduğunu varsaydı; otomatik olarak yaratan. İyi ki APK Oluşturucum var.

E: NumPad / res / values ​​/ colours.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
</resources>

F: NumPad / res / values ​​/ strings.xml

<resources>
    <string name="app_name">Suragch NumPad</string>
</resources>

G: NumPad / res / values ​​/ styles.xml

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="android:Theme.Material.Light.DarkActionBar">
        <!-- Customize your theme here. -->
    </style>

</resources>

H: Numpad / AndroidManifest.xml

Bu gerçekten tartışmaya açık olan dosya. Burada programımı asla derleyemeyeceğimi hissettim. hıçkırık hıçkırık Suracgh'ın cevabını kontrol ederseniz, ilk alan grubunu boş bıraktığını ve bu dosyaya etkinlik etiketini eklediğini görürsünüz. Dediğim gibi dört tür Android programı var. Etkinlik, başlatıcı simgesi olan normal bir uygulamadır. Bu sayısal tuş takımı bir etkinlik değil! Ayrıca herhangi bir faaliyette bulunmadı.

Arkadaşlarım etkinlik etiketini eklemiyor. Programınız derlenecek ve başlatmaya çalıştığınızda çökecek! Xmlns'e gelince: android ve uses-sdk; Orada sana yardım edemem. Çalışırlarsa ayarlarımı deneyin.

Gördüğünüz gibi onu servis olarak kaydeden bir servis etiketi var. Ayrıca service.android:name java dosyamızdaki genel sınıf genişletme hizmetinin adı olmalıdır. Buna göre büyük harfle yazılmalıdır. Ayrıca paket, java dosyasında beyan ettiğimiz paketin adıdır.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="Saragch.num_pad">

    <uses-sdk
        android:minSdkVersion="12"
        android:targetSdkVersion="27" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/Suragch_NumPad_icon"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <service
            android:name=".MyInputMethodService"
            android:label="Keyboard Display Name"
            android:permission="android.permission.BIND_INPUT_METHOD">

            <intent-filter>
                <action android:name="android.view.InputMethod"/>
            </intent-filter>

            <meta-data
                android:name="android.view.im"
                android:resource="@xml/method"/>

        </service>

    </application>
</manifest>

I: NumPad / src / Saragch / num_pad / MyInputMethodService.java

Not: Java'nın src'ye bir alternatif olduğunu düşünüyorum.

Bu başka bir sorun dosyasıydı, ancak bildirim dosyası kadar çekişmeli değildi. Java'yı bildiğim kadarıyla neyin neyin neyin olmadığını bilecek kadar iyi. Xml'yi ve Android geliştirmeyle nasıl bağlantılı olduğunu çok az biliyorum!

Buradaki sorun, hiçbir şey ithal etmemesiydi! Demek istediğim, bize çözülemeyen isimler kullanan "eksiksiz" bir dosya verdi! InputMethodService, Keyboard, vs. Bu kötü bir uygulama Bay Suragch. Bana yardım ettiğiniz için teşekkürler ama isimler çözülemezse kodun nasıl derlenmesini bekliyorsunuz?

Doğru düzenlenmiş versiyon aşağıdadır. Tam olarak neyi ithal edeceğimi öğrenmek için beni doğru yere götürmek için birkaç ipucu buldum.

package Saragch.num_pad;

import android.inputmethodservice.InputMethodService;
import android.inputmethodservice.KeyboardView;
import android.inputmethodservice.Keyboard;

import android.text.TextUtils;
import android.view.inputmethod.InputConnection;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;


public class MyInputMethodService extends InputMethodService implements KeyboardView.OnKeyboardActionListener 
{
    @Override
    public View onCreateInputView() 
    {
     // get the KeyboardView and add our Keyboard layout to it
     KeyboardView keyboardView = (KeyboardView)getLayoutInflater().inflate(R.layout.keyboard_view, null);
     Keyboard keyboard = new Keyboard(this, R.xml.number_pad);
     keyboardView.setKeyboard(keyboard);
     keyboardView.setOnKeyboardActionListener(this);
     return keyboardView;
    }

    @Override
    public void onKey(int primaryCode, int[] keyCodes) 
    {

        InputConnection ic = getCurrentInputConnection();

        if (ic == null) return;

        switch (primaryCode)
        {
         case Keyboard.KEYCODE_DELETE:
            CharSequence selectedText = ic.getSelectedText(0);

            if (TextUtils.isEmpty(selectedText)) 
            {
             // no selection, so delete previous character
             ic.deleteSurroundingText(1, 0);
            }

            else 
            {
             // delete the selection
             ic.commitText("", 1);
            }

            ic.deleteSurroundingText(1, 0);
            break;

         default:
            char code = (char) primaryCode;
            ic.commitText(String.valueOf(code), 1);
        }
    }

    @Override
    public void onPress(int primaryCode) { }

    @Override
    public void onRelease(int primaryCode) { }

    @Override
    public void onText(CharSequence text) { }

    @Override
    public void swipeLeft() { }

    @Override
    public void swipeRight() { }

    @Override
    public void swipeDown() { }

    @Override
    public void swipeUp() { }
}
  1. Projenizi derleyin ve imzalayın.

    Yeni bir Android geliştiricisi olarak bilgisiz olduğum yer burası. Gerçek programcıların manuel olarak derleyebileceğine inandığım için bunu manuel olarak öğrenmek isterim.

Gradle'ın apk'ye derlemek ve paketlemek için kullanılan araçlardan biri olduğunu düşünüyorum. apk bir jar dosyası veya zip dosyası için bir rar gibi görünüyor. O halde iki tür imzalama vardır. oyun deposunda ve özel anahtarda izin verilmeyen hata ayıklama anahtarı.

Bay Saragch'a yardım edelim. Ve videomu izlediğiniz için teşekkür ederim. Abone olun.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.