Ana içeriğe atla

17. Android’e Pusula View’u Oluşturma Örneği

1. View uzatarak CompassView sınıfını oluşturun. Yapılandırıcılar oluşturarak view’un kod içinde ve harici bir kaynak olarak örneklendirilmesine imkan verin. Kontrolü örneklemek ve diğer yapılandırıcılardan çağırabilmek için yeni bir initCompassView metodu ekleyin.

package com.paad.compass;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.*;
import android.view.*;
import android.util.AttributeSet;
public class CompassView extends View {
  public CompassView(Context context) {
    super(context);
    initCompassView();
  }  
  public CompassView(Context context, AttributeSet attrs) {
    super(context, attrs);
    initCompassView();
  }
  public CompassView(Context context, AttributeSet attrs, int defaultStyle) {
    super(context, attrs, defaultStyle);
    initCompassView();
  }
protected void initCompassView() {
    setFocusable(true);
  }
}

2. Pusula kontrolü canvas’ın müsaade ettiği ölçüde büyük, tam bir daire olmalıdır. OnMeasure metodunu ezerek en kısa kenarın ölçüsünü hesaplayın ve setMeasuredDimension metodunu kullanarak yükseklik ve genişliğin değerlerini ayarlayın.

@Override   
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int measuredWidth = measure(widthMeasureSpec);
    int measuredHeight = measure(heightMeasureSpec);
    int d = Math.min(measuredWidth, measuredHeight);
    setMeasuredDimension(d, d);   
  }
  private int measure(int measureSpec) {
    int result = 0;
    int specMode = MeasureSpec.getMode(measureSpec);
    int specSize = MeasureSpec.getSize(measureSpec);
    if (specMode == MeasureSpec.UNSPECIFIED) {
      result = 200;
    } else {
      result = specSize;
    }
    return result;
  }

3. String değerler için res/values/strings.xml kaynağını oluşturun.

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <string name="app_name">Compass</string>
  <string name="cardinal_north">N</string>
  <string name="cardinal_east">E</string>
  <string name="cardinal_south">S</string>
  <string name="cardinal_west">W</string>
</resources>

4. Renkler için res/values/colors.xml kaynağını oluşturun.


<?xml version="1.0" encoding="utf-8"?>
<resources>   
  <color name="background_color">#F555</color>
  <color name="marker_color">#AFFF</color>
  <color name="text_color">#AFFF</color>
</resources>

5. CompassView sınıfına geri dönün ve görüntülenen yönü saklamak için yeni bir property ekleyin ve get ve set metodlarını oluşturun.

private float bearing;
  public void setBearing(float _bearing) {
    bearing = _bearing;
  }
  public float getBearing() {
    return bearing;
  }

6. initCompassView metoduna geri dönün ve 3. Adımda oluşturulan kaynaklar için referanslar alın. String değerleri değişkenlerde saklayın ve yeni sınıf bazlı Paint objeleri için renk değerlerini kullanın.


private Paint markerPaint;
  private Paint textPaint;
  private Paint circlePaint;
  private String northString;
  private String eastString;
  private String southString;
  private String westString;
  private int textHeight;
  protected void initCompassView() {
    setFocusable(true);
    Resources r = this.getResources();
    northString = r.getString(R.string.cardinal_north);
    eastString = r.getString(R.string.cardinal_east);
    southString = r.getString(R.string.cardinal_south);
    westString = r.getString(R.string.cardinal_west);
    circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    circlePaint.setColor(R.color.background_color);
    circlePaint.setStrokeWidth(1);
    circlePaint.setStyle(Paint.Style.FILL_AND_STROKE);
    markerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    markerPaint.setColor(r.getColor(R.color.marker_color));
    textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    textPaint.setColor(r.getColor(R.color.text_color));
    textHeight = (int)textPaint.measureText("yY");
  }

7. CompassView sınıfı içindeki onDraw metodunu ezerek başlayın.

8. Kontrolün merkezini bulun ve kısa kenarı pusulanın yarıçapı olarak atayın.

9. drawCircle metodunu kullanarak dış kenarlığı çizin ve pusulanın arka planını renklendirin. 6. Adımda oluşturduğunuz circlePaint objesini kullanın.

10. Pusulamız çevrildiği yönü gösterecek o halde cihazın üstü hep gösterilen yön olmalıdır. Bunu sağlamak için canvas’ı o anki yönün tersine döndürmeliyiz.

11. Artık yapmanız gereken son şey işaretleri çizmek. Her 15 derecede bir işaret ve her 45 derecede bir de dereceyi yazacağız.


@Override
  protected void onDraw(Canvas canvas) {
    int px = getMeasuredWidth() / 2;
    int py = getMeasuredHeight() / 2;
    int radius = Math.min(px, py);
    canvas.drawCircle(px, py, radius, circlePaint);
    canvas.save();
    canvas.rotate(-bearing, px, py);
    int textWidth = (int)textPaint.measureText("W");
    int cardinalX = px-textWidth/2;
    int cardinalY = py-radius+textHeight;
    for (int i = 0; i < 24; i++) {
      canvas.drawLine(px, py-radius, px, py-radius+10, markerPaint);
      canvas.save();
      canvas.translate(0, textHeight);
      if (i % 6 == 0) {
        String dirString = "";
        switch (i) {
          case(0)  : {
                       dirString = northString;
                       int arrowY = 2*textHeight;
                       canvas.drawLine(px, arrowY, px-5, 3*textHeight, markerPaint);
                       canvas.drawLine(px, arrowY, px+5, 3*textHeight, markerPaint);
                       break;
                     }
          case(6)  : dirString = eastString; break;
          case(12) : dirString = southString; break;
          case(18) : dirString = westString; break;
        }
        canvas.drawText(dirString, cardinalX, cardinalY, textPaint);
      }
      else if (i % 3 == 0) {
        String angle = String.valueOf(i*15);
        float angleTextWidth = textPaint.measureText(angle);
        int angleTextX = (int)(px-angleTextWidth/2);
        int angleTextY = py-radius+textHeight;
        canvas.drawText(angle, angleTextX, angleTextY, textPaint);
      }
      canvas.restore();
      canvas.rotate(15, px, py);
    }
    canvas.restore();
  }

12. Pusulayı görüntülemek için main.xml planını değiştirin ve TextView referansını CompassView ile değiştirin.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <com.paad.compass.CompassView
    android:id="@+id/compassView"
    android:layout_width="fill_parent"           
    android:layout_height="fill_parent"
  />
</LinearLayout>

Yorumlar

Bu blogdaki popüler yayınlar

Basit ve Dinamik Disk Nedir? Birbirine Nasıl Dönüştürülür?

Sabit diskler Windows 2000 işletim sistemine kadar sadece temel disk (basic disk) olarak ayarlanabiliyordu. Temel disk en fazla 4 birincil bölüm (primary partition) veya 3 primary ve 1 genişleyebilir bölüm (extended partition) şeklinde yapılandırılabilir. Bir temel diskte sadece 1 tane extended partition oluşturulabilir ve sadece primary partitionlara işletim sistemi kurulabilir. Windows 2000 ile gelen dinamik disk teknolojisi, Windows 2000 den sonraki tüm Windowssürümlerinde kullanılabilmektedir. Dinamik disk kavramıyla bölüm (partition) kavramı yerinihacim (volume) kavramına bırakmıştır. Dinamik disklerde, temel disklerde olduğu gibi bir sınırlama yoktur. İstenildiği kadar volume oluşturabilir, temel disk istenirse dinamik hale getirebilir ve bu işlem esnasında herhangi bir veri kaybı yaşanmaz. Fakat dinamik diskler temel diske çevirildiğinde bir veri kaybı söz konusu olacaktır. Temel diskin bilgileri kayıt defterinde tutulur. Dinamik diskin bilgileri kendi üstünde tutulur.

Einstein'in Rölativite Kuramına Bakış

Bu yüzyılın başlarında kuramsal fizikte altın çağ başladığı zaman, adı henüz bilim dünyasında duyulmamış bir fizikçi vardı. Bu, Annalen der Physık’in 1905 tarihli sayısında fotoelektrik olayı, Brown hareketi ve özel görelilikle ilgili ünlü üç çalışmasını birden yayınlayarak üne kavuşan Albert Einstein’dır. Onun fizikteki hayat boyu çalışmaları bilimin felsefesi ve yöntemleri üzerinde büyük etki yaptı. Einstein’ın kendisi bilimci filozoftu. Bu yüzyılın başlarında kuramsal fizikte altın çağ başladığı zaman, adı henüz bilim dünyasında duyulmamış bir fizikçi vardı. Bu, Annalen der Physık’in 1905 tarihli sayısında fotoelektrik olayı, Brown hareketi ve özel görelilikle ilgili ünlü üç çalışmasını birden yayınlayarak üne kavuşan Albert Einstein’dır. Onun fizikteki hayat boyu çalışmaları bilimin felsefesi ve yöntemleri üzerinde büyük etki yaptı. Einstein’ın kendisi bilimci filozoftu. O, hayranlık uyandırıcı bir şekilde felsefeyi kullanarak bugün modern bilimin önemli bir kısmı olan buluşlarını

Rubik Küp Nasıl Çözülür?

Rubik küp 3x3x3 veya 4x4x4 gibi karesel formatta ve her kenarı farklı renkte olan bir küptür. Bu küpün; sabır küpü, sinir küpü, zekâ küpü, renk küpü, Rubikin küpü, sihirli küp (magic box), 3d Puzzle, gibi birçok değişik adı vardır. Unutulmamalıdır ki küpün çözümü için geliştirilmiş bir algoritma vardır. Bu küp ezbere çözülemez. Bu yazıda sizlere küpün en yaygın çözümü anlatılacaktır. Hata yaptığınız yerde hatayı düzeltmeye çalışmayın belirtilen algoritma çerçevesinde çözüme baştan başlayın. Hala küpü çözemediyseniz buradaki yazımızda belirtilen otomatik çözen programları deneyebilirsiniz. Öncelikle bilmeniz gerekenler: Küpün parçaları birbirinden bağımsız değildirler. Küpün orta noktası daima sabittir. Küpü ne kadar çevirirseniz çevirin değişmezler. Kırmızının karşısında daima turuncu, yeşilin karşısında mavi, sarının karşısında beyaz vardır. Bir küp, toplam 26 adet parçadan oluşmaktadır: 8 adet üç renkli köşe parçası, 12 adet iki renkli parça ve 6 adet de sabit tek ren