4 Kasım 2016 Cuma

Android Material Transition Animation



Bu proje bir arkadaşımın çook güzel bir tasarımından ilham alınarak yapıldı.
Arkadaşım: https://twitter.com/ebruhu
Tasarım: https://material.uplabs.com/posts/material-transition-animation

Kaynak Kod: https://github.com/Cutta/MaterialTransitionAnimation
Kodlarken yardımcı olan arkadaşım: https://github.com/andanicalik
(Sol: Tasarım, Sağ: Uygulama)


     Söz konusu tasarım sol tarafta ve sağ taraftaki de ilham alınarak yapılmaya çalışılmış mobil uygulaması.İlk bakışta göze çarpan farklılıklar elbette mevcut ancak yaparken amacım, %100 aynısını yapmak olmadı. Kendimce yapılmasını zor gördüğüm kısımlara daha çok odaklandım.
     Başlama motivasyonum tamamen tasarımın çok güzel olması ve uygulamaya çalışırken beni zorlayacak olmasıydı. Tam da öyle oldu. Özellikle listenin scroll durumunda liste elemanlarının arasındaki boşluğun açılması ne daha önce bir uygulamada gördüğüm ne de uygulama fırsatı bulabildiğim bir şeydi. Tasarımı hoş kılan en önemli özellik de buydu.
1. Ekran: - Yukarı yönde scroll olmaya başladığı anda üst kısımda bulunan başlık ve edittext animasyon ile kaybolmalı
- Aşağı yönde scroll olurken listenin sonuna geldiysek ve listemiz ilk pozisyonunu aldıysa üst kısım animasyon ile geri açılmalı

- Scroll durumunu yakalanmalı
- Ekranda görünen liste elemanları(item) na bu durumu iletilmeli
- Liste elemanlarının bu durum karşısında aralarındaki boşluk (margin)  yavaşça açılmalı
- Scroll durunca margin azaltılarak boşluk yavaşça kapatılmalı.

 Scroll durumunu yakalanmalı
Listeyi oluşturmak için RecyclerView yapısını kullandığımız için RecyclerView.OnScrollListener  abstract class'ı ile listenin scroll durumundan haberdar oluyoruz.

 Ekranda görünen liste elemanları(item) na bu durumu iletilmeli
OnScrollListener sayesinde yakaladığımız bu durumu listenin elemanlarına EventBus ile haber ediyoruz. Liste elemanları RelativeLayout' tan extend edilen bir bir class ile oluşturuluyor.

 Liste elemanlarının bu durum karşısında aralarındaki boşluk (margin)  yavaşça açılmalı
Scroll durunca margin azaltılarak boşluk yavaşça kapatılmalı.

Burda da yardımımıza ValueAnimator yetişiyor. Çok hoş bir kullanımı mevcut. x değerinden y değerine şu kadar milisaniyede geçiş yap deyip geçiş yaparken şu işlemi yap diyebiliyoruz.
Anlatımımın eksik kaldığına eminim kodu görerek bu açıklamamdan daha çok şey anlayabilirsiniz.

 1. Ekrandan 2. Ekrana GeçişActivity geçişlerinde animasyon verebilmek için android bizim için işi çok kolay bir hale getiriyor.
https://android.jlelse.eu/easy-android-shared-element-transition-ac36952a4a4#.qhvqe1c58 burada oldukça güzel açıklanmış. Bir kaç adımda güzel bir animasyon katabilmeniz mümkün.

Bunlar dışında kalan özellikler standart işlemler olduğu için açıklayıp yazıyı uzatmak istemedim.

Kodu incelemek isteyenler buradan yaksın: https://github.com/Cutta/MaterialTransitionAnimation
Herkese kolay gelsin.

24 Ağustos 2016 Çarşamba

Android Reveal Animation Kullanımı


Bu animasyonu en çok WhatsApp dan hatırlayacaksınız diye düşünüyorum. Konuşma esnasında bir şey göndermek istediğimizde sağ üst köşeden ataç simgesine dokunuyoruz ve o sihirli seçim ekranı oluşuyor. Özellikle dokunulan yerden oluşmaya başlaması kullanıcıya güzel bir görüntü sunuyor. UI, UX bu konular benlik değil abi koda gel, ben nasıl yapıldığına bakarım diyorsan hemen seni dinliyorum ve işin teknik kısmına değinmeye çalışıyorum. :)
Öncelikle bu iş için kullandığım kütüphane : https://github.com/ozodrukh/CircularReveal
Github sayfasında da belirttiği gibi bu kütüphane sayesinde api level 14+ herkese ulaşabiliyoruz.

Bu animasyon işlemini yapabilmek için Android'in bize sunduğu sunduğu ViewAnimationUtils sınıfını kullanıyoruz. Bu sınıfta da bir tane  createCircularReveal adında static metodumuz mevcut.
Parametreleri şöyle:

Animator createCircularReveal (
View view,
int centerX,
int centerY,
float startRadius,
float endRadius);

Yani diyorki :
 "Hangi view' e bu işlemi uygulayacağım?",
 "X ekseninde merkezi kaç olacak?",
 "X ekseninde merkezi kaç olacak?",
 "Başlangıç için çapım ne olacak",(Circular olduğunu unutmayalım)
 "Bitiş için çapım ne olacak".
Başlangıç ve bitiş çaplarını gösterip, kaybederken kullanacağız.
Animasyon ile başlatırken startRadius = 0,
animasyon ile kapatırken endRadius = 0 değerini veriyoruz.

"startRadius = 0" diyerek circular animasyonumuz için merkezden(0 noktasından) başla demiş oluyoruz.
aynı şekilde  "endRadius = 0" diyerek kapanan animasyona merkeze (0 noktasına) gelene kadar küçül diyoruz.

Kodu görmek isteyenler, üstünde oynama yapacaklar için github linki:
https://github.com/Cutta/RevealAnimation

Herkese kolay gelsin.

29 Aralık 2015 Salı

Android GifView

Öncelikli github linkini vereyim sonra biraz açıklamaya çalışayım. 
https://github.com/Cutta/GifView

Android için gif oynatmanın bir kaç yolu mevcut ancak en sağlıklı bulduğum bu yöntemi biraz sadeleştirerek sunmak istedim. Bu yöntemde gif lerimizi androidin bize sağladığı Movie class ının yardımıyla oynatacağız.
GifView.java classından biraz bahsetmem gerekirse. Asıl işin burada döndüğünü kodlara bakınca da anlayacaksınız. Gif oynatma, durdurma, kaynağını belirleme, boyutlandırma gibi işlemlerin hepsi bu sınıfta meydana geliyor.Bu sınıf ise View classından extend ediliyor.
 Gifleri frame frame gösterebilmek için çalıştığımız class ise yine androidin bize sunduğu  Canvas classı. Aslında yaptığımız şey Movie classına gifin her sahnesini canvas vasıtası ile iletmek ve oluşan görüntüyü View classından extend ettiğimiz için override edebildiğimiz onDraw metodunda  "al bunu göster" diyebilek olarak özetlenebilir.
Umarım işinize yarar.




17 Aralık 2015 Perşembe

Android EventBus Nedir?


       EventBus proje içerisinde olayları(event) rahatlıkla yakalayabilmemiz için geliştirilmiş bir kütüphane.
        Fragment, Activity, Thread, Service vb sınıflar arasında kolayca parametre akışı sağlamamıza yardımcı olur. Eski usül yöntem ile, Java' nın bize sağladığı interface ile bunu yapmak mümkün evet. Yani bir fragmentte tetiklenen bir olay başka bi event ya da activityde interface'ı implement ettiğimiz taktirde yakalanabilir. Ancak bunun olumsuz yanı kodu okunabilirlikten çok uzak kılıyor ve yeni bir şeyler yapmak istediğinizde iş gerçekten karışıyor. Böyle düşünen yalnızca ben değilmişim ki 7 bin üzerinde star alan GreenRobot EventBus  kütüphanesi ve tabi ki olmazsa olmaz Square şirketinin Otto kütüphanesi epey popüler.
        Kullanım açısından ikisi neredeyse aynı diyebiliriz ancak aşağıdaki karşılaştırma tablosunun bize söyleyecekleri var :)
                       

        Kullanımından da biraz bahsedecek olursam.
        Her olaya özgü Event classları oluşturuyoruz. Bu classları özel kılan bi durum yok. Normal değişkenler ve setter getter methodları olan bir class düşünebiliriz.
        Olayın meydana geldiği fragment ya da activity de olayın meydana geldiğini tek satırda söylüyoruz.

   EventBus.getDefault().post(new ActivityEvent("Event sent by MainActivity"));

        Bu satırda anlatılmak istenen gelinen satırda ActivityEvent olayının meydana geldiği.
        Bu olayı başka bi sınıfta yakalamak istiyorsak öncelikle olayları yakalamak istediğimizi söylüyoruz. Yani register işlemi. Bu işlemi fragment, activity ya da service sınıflarında onCreate methodlarında yerine getiriyoruz. Bu işlem de yalnızca tek satır.

  EventBus.getDefault().register(this);

        Aynı şekilde işimizin bittiğini ve artık olaylardan haberdar olmak istemediğimizi de söylememiz gerekiyor. Bunu da onDestroy methodunda yerine getiriyoruz.
@Overrideprotected void onDestroy() {
    EventBus.getDefault().unregister(this);    super.onDestroy();}
        Şimdi gelelim olayı yakaladığımız yere. Bunun için olayı yakalamak istediğimiz yerde onEvent adlı methodlar oluşturmamız gerekiyor ve bu methodlara hangi olaylarla ilgileniyorsak onu parametre olarak vermemiz gerekiyor. Yani birden fazla olaylı yakalayabiliriz.
public void onEvent(ActivityEvent event) {

    ...
}
        Kullanımı gerçekten çok çok kolay.
        Buradaki anlatım eksik ya da karışık gelmiş olabilir. Örnek proje Github' da mevcut. Oradan clonelayıp inceleyebilirsiniz.
        https://github.com/Cutta/EventBusSample
        Kolay gelsin.

27 Eylül 2015 Pazar

Adroid TagView





Öncelikle github linkini vereyim sonra hemen konuya başlayalım.

Android için tag görünümü gereken bir uygulama üzerinde çalışırken  bazı benzer kütüphaneleri harmanlayarak yeni bir repo oluşturdum. Harmanlama ihtiyacım şu yüzden oldu.
Taglerin silinebilmeleri gerekiyordu ve benim ilk kullandığım kütüphanede bu özellik mevcut değildi. Bu özelliğin mevcut olduğu kütüphanede de onaylama mekanızması yoktu yani silmeye yanlışlıkla basınca geri dönüşü olmuyordu.
Biraz araştırınca işime yarar görünüme ve işleve kavuşturabildim. Umarım sizlerin de işine yarar.


25 Haziran 2015 Perşembe

Android Double Tap To Like (Çift Dokunma-Beğnme)


Öncelikle github linkine buradan ulaşabilirsiniz: https://github.com/Cutta/Double-Tap-To-Like
Türkçe olarak tam karşılığını bulamasam da "beğenmek için çift dokuma" demek istiyorum.
Instagram'dan sonra ondan etkilenen uygulamalarda da görebileceğimiz üzere iki kere artarda tıklama ve beğeni aksiyonunun android için uyarlanmış basit bir örnek kodunu yazdım.


Üzerinde çalıştığımız bir projede gereken bu durum için önce iki defa tıklama durumunu tespit ettik.
Bu durumu Android' in bize sağladığı GestureDetector sınıfı ile çözdük. Bundan sonraki aşama da Instagram' daki gibi kalp animasyonu ile kullanıcıya beğendiğini anlatabilmekti.
Bunu da yine Androidin bize sağladığı  Animation  sınıfı  ile çözüme kavuşturduk.
Senaryoya göre kullanıcı resime iki defa tıklayacak ve animasyonumuz ekranda oynayarak kullanıcıya beğendiğini anlatacak. Instagram kullananlar zaten yakından bilir, kullanmayanlar da aşinadır eminim, zira ben kullanmıyorum ama biliyorum =)

Bu özellik diğer uygulamlarda da karşımıza çıkıyor ve standartlaşmak üzere bir yolda ilerliyor. Eskiden iki tıkla resim yaklaştırılırdı ama artık insanlar diğer uygulamalar da dahi temkinli oluyorlar "iki defa tıklarsam beğenir mi acaba?" diye kafalarında soru oluşabiliyor.

Bu durumu özetleyen, içinde basit bir resim galerisi barındıran bir yardımcı proje oluşturdum.
Projeye aşağıdaki linkten ulaşabilirsiniz. İndirdikten sonra import ederek çalıştırabilirsiniz
https://github.com/Cutta/Double-Tap-To-Like

13 Mayıs 2015 Çarşamba

Android Blur Resim Oluşturma (blur - image)

Şimdiye kadar üzerinde çalıştığım projeler arasında bir kaç kere blur görüntülerle uğraşmak zorunda kaldım. Bir çok metodunu buldum aslında ama kulağı ters taraftan tutmak vardır ya öyle yapmışlar gibi geldi bana =) Özellikle ilk defa blurlama işlemi ile uğraştığımda android geliştirmede yeniydim ve epey zorlanmıştım açıkçası. İkinci sefer karşılaştığımda o kadar zorlanmadım ama yine de uzun bir metoddu, Kod düzenime uymuyordu ve hakim olamıyordum kodlara tam manasıyla. Uğraşırken farklı örneklerde aslında özde aynı şeylerin yapıldığını gördüm bunları biraz derledim açıkçası ben de.
Androidde var olan şu kütüphaneleri kullanarak işlemlerimi gerçekleştiriyorum.

android.renderscript.RenderScript ,
 android.renderscript.ScriptIntrinsicBlur.
Kullandığım iki metodda blurluğun seviyesini  blur.setRadius(20.0f); satırında belirliyorum. Bu float değer 0 ile 25 değeri arasında kabul ediliyor sadece buna dikkat etmek lazım. Kodları indirmek istemeyen olursa kısaca burda örnek kodu yazayım.
İndirmek isteyenelr için link: https://github.com/Cutta/Simple-Image-Blur

imageview = (ImageView) itemView.findViewById(R.id.imageView); BitmapDrawable drawable = (BitmapDrawable) imageview.getDrawable();// var olan resmimizi bitmape ceviriyoruz Bitmap bitmap = drawable.getBitmap(); Bitmap blurred = blurRenderScript(bitmap, 20);//blurlanacak resmi ve, blur miktarini yolluyoruz imageview.setImageBitmap(blurred);// donen blur resmi ekranda gosteriyoruzz
@SuppressLint("NewApi")
private Bitmap blurRenderScript(Bitmap smallBitmap, int radius) {
try {
smallBitmap = RGB565toARGB888(smallBitmap);
} catch (Exception e) {
e.printStackTrace();
}
Bitmap bitmap = Bitmap.createBitmap(
smallBitmap.getWidth(), smallBitmap.getHeight(),
Bitmap.Config.ARGB_8888);
RenderScript renderScript = RenderScript.create(context);
Allocation blurInput = Allocation.createFromBitmap(renderScript, smallBitmap);
Allocation blurOutput = Allocation.createFromBitmap(renderScript, bitmap);
ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(renderScript,
Element.U8_4(renderScript));
blur.setInput(blurInput);
blur.setRadius(radius); // radius must be 0 < r <= 25
blur.forEach(blurOutput);
blurOutput.copyTo(bitmap);
renderScript.destroy();
return bitmap;
}
private Bitmap RGB565toARGB888(Bitmap img) throws Exception { int numPixels = img.getWidth() * img.getHeight(); int[] pixels = new int[numPixels];
//Get JPEG pixels. Each int is the color values for one pixel. img.getPixels(pixels, 0, img.getWidth(), 0, 0, img.getWidth(), img.getHeight()); //Create a Bitmap of the appropriate format. Bitmap result = Bitmap.createBitmap(img.getWidth(), img.getHeight(), Bitmap.Config.ARGB_8888); //Set RGB pixels. result.setPixels(pixels, 0, result.getWidth(), 0, 0, result.getWidth(), result.getHeight()); return result; }