13 Şubat 2021 Cumartesi

Android Kütüphane Sistemi Mobil Uygulaması - 5 (Anasayfa)

  Merhabalar. Android Kütüphane Sistemi Mobil Uygulaması yazı dizisinin beşinci yazısı ile yeniden sizlerleyim. Bu yazıda sisteme giriş yaptıktan sonra açılan anasayfadan yani dashboard ekranından bahsedeceğim.Tekrar belirtmekte fayda olacak, uygulamanın kodlarına buradan erişebilirsiniz.

  Bir önceki yazımda sol menüden de ulaşılabilir olan ve uygulama açıldığında bizi ilk karşılayan kısmın AnasayfaFragment olduğundan bahsetmiştim. İlk setlenen fragment'ın bu fragment olması aşağıda ki kod parçacığı ile olmaktadır.

            tempFragment = AnasayfaFragment();

     supportFragmentManager.beginTransaction()
.replace(R.id.fragmentNavTutucu,tempFragment).commit();


Burada önemle belirtmek gerekir ki yukarıda fragmentları manuel olarak yönetmek amelelik olmakla birlikte bu fragmentların navigation unu Jetpack kütüphanesi ile idare etmek hem kod açısından hem de transaction yönetimi açısından oldukça kolaylaştırılmıştır. İlerleyen zamanlarda kodun bu kısmında güncelleme yapıp sizlerle paylaşacağım.

AnasayfaFragment ın görünümü aşağıda ki gibidir.



Burada İstatistikler i gösterdiğim Piechart için MPAndroidChart ,yuvarlak resimler için ise CircularImageview kütüphanelerinden yararlandım. Bu kütüphaneleri kullanabilmeniz için build.gradle (Module:app) dosyasının dependencies kısmına aşağıda ki satırları eklemeniz gerekmektedir. 

          implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'

    implementation 'com.mikhaellopez:circularimageview:4.2.0'

Fragment kitap türleri ve son beş kitabı gösteren 2 Recyclerview ve en altta ise bir PieChart içermektedir. 

fragment_anasayfa.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
style="@style/loginParent">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/kitapTurlerDashboardLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<TextView
android:id="@+id/kitapturlerDashboardTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_marginLeft="13dp"
android:layout_marginTop="25dp"
android:fontFamily="@font/alegreya"
android:text="@string/dashKitapTurlerLabel"
android:textColor="@color/siyah"
android:textSize="20sp"
android:textStyle="bold" />
</RelativeLayout>

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/dashKitapTurlerRw"
android:layout_marginTop="20dp"
android:layout_below="@id/kitapTurlerDashboardLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

<RelativeLayout
android:id="@+id/sonEklenenKitaplarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/dashKitapTurlerRw">

<TextView
android:id="@+id/sonEklenenKitaplarTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_marginLeft="13dp"
android:layout_marginTop="25dp"
android:fontFamily="@font/alegreya"
android:text="@string/sonEklenenKitaplarLabel"
android:textColor="@color/siyah"
android:textSize="20sp"
android:textStyle="bold" />
</RelativeLayout>

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/sonEklenenKitaplar"
android:layout_marginTop="20dp"
android:layout_below="@id/sonEklenenKitaplarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

<RelativeLayout
android:layout_marginTop="20dp"
android:layout_width="wrap_content"
android:layout_below="@+id/sonEklenenKitaplar"
android:layout_height="wrap_content">
<TextView
android:id="@+id/istatistiklerTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_marginLeft="13dp"
android:layout_marginTop="25dp"
android:fontFamily="@font/alegreya"
android:text="@string/istatistiklerLabel"
android:textColor="@color/siyah"
android:textSize="20sp"
android:textStyle="bold" />

<com.github.mikephil.charting.charts.PieChart
android:id="@+id/pieChart"
android:layout_marginTop="25dp"
android:layout_width="match_parent"
android:layout_height="300dp" />

</RelativeLayout>
</LinearLayout>
</ScrollView>
</RelativeLayout>

Burada ki RecyclerView lar gösterim için birer adapter ve layout a sahiptir. İlk olarak fragment ın kodlarına bakalım. Zaten adapterların setlendiği yerde AnasayfaFragment ' da.

AnasayfaFragment.kt

class AnasayfaFragment:Fragment() {

private lateinit var anasayfaView:View;
private lateinit var sonEklenenKitaplar:RecyclerView;
private lateinit var pd: Dialog;
private lateinit var kitapService: IKitapIslemService;
private lateinit var kullaniciService:IKullaniciService;
private lateinit var dashKitapTurlerRw:RecyclerView;
private lateinit var kitapTurIstatistik:PieChart;
private lateinit var pieEntry:ArrayList<PieEntry>;

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
anasayfaView = inflater.inflate(R.layout.fragment_anasayfa,container,false);
initComponents();

return anasayfaView;
}

private fun initComponents() {
this.sonEklenenKitaplar = this.anasayfaView.findViewById(R.id.sonEklenenKitaplar) as RecyclerView;
kitapService = WebApiUtil.getKitapService(context!!);
kullaniciService = WebApiUtil.getKullaniciService();
this.dashKitapTurlerRw = this.anasayfaView.findViewById(R.id.dashKitapTurlerRw) as RecyclerView;
this.kitapTurIstatistik = this.anasayfaView.findViewById(R.id.pieChart) as PieChart;

activity!!.hizliErisimFabButton.visibility = View.VISIBLE;

val sonKitaplarLayout = LinearLayoutManager(context!!,LinearLayoutManager.HORIZONTAL, false);
sonEklenenKitaplar.setHasFixedSize(true);
sonEklenenKitaplar.layoutManager = sonKitaplarLayout;

val dashKitapturlerLayout = LinearLayoutManager(context!!,LinearLayoutManager.HORIZONTAL, false);
dashKitapTurlerRw.setHasFixedSize(true);
dashKitapTurlerRw.layoutManager = dashKitapturlerLayout;

pd = Dialog(activity!!);
val pdView: View = layoutInflater.inflate(R.layout.custom_progress_dialog,null);
pd.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT));
pd.setTitle(null);
pd.setContentView(pdView);
pd.setCancelable(false);

this.loadSon5Kitap();
this.loadKitapTurleri();
this.loadKitapTurIstatistikler();
}

private fun loadKitapTurleri(){
pd.show();
kullaniciService.getKitapturListe().enqueue(object:
Callback<ArrayList<IlgiAlanlariParametreModel>> {
override fun onFailure(call: Call<ArrayList<IlgiAlanlariParametreModel>>?, t: Throwable) {
SimpleToast.error(activity!!.applicationContext, resources.getString(R.string.kitapTurListeHata), "{fa-times-circle}");
pd.dismiss();
}

override fun onResponse(call: Call<ArrayList<IlgiAlanlariParametreModel>>?, response: Response<ArrayList<IlgiAlanlariParametreModel>>) {
val ilgiAlanlariListe = response.body() as ArrayList<IlgiAlanlariParametreModel>;
val adapter = DashKitapturAdapter(activity!!.applicationContext,ilgiAlanlariListe);
dashKitapTurlerRw.adapter = adapter;
pd.dismiss();
}
});
}

private fun loadSon5Kitap(){
pd.show();
val jsonObj: JSONObject = JSONObject();
jsonObj.put("minKayitNum",0);
jsonObj.put("maxKayitNum",5);
kitapService.getKitapListe(jsonObj.toString()).enqueue(object:
Callback<ArrayList<KitapModel>> {
override fun onFailure(call: Call<ArrayList<KitapModel>>?, t: Throwable) {
Log.d("Exception",""+t.localizedMessage);
SimpleToast.error(context, resources.getString(R.string.kitapListeHata), "{fa-times-circle}");
pd.dismiss();
}

override fun onResponse(call: Call<ArrayList<KitapModel>>?, response: Response<ArrayList<KitapModel>>) {
val liste = response.body() as ArrayList<KitapModel>;
val kitapAdapter:DashKitapAdapter = DashKitapAdapter(context!!,liste);
sonEklenenKitaplar.adapter = kitapAdapter;
pd.dismiss();
}
});
}

private fun loadKitapTurIstatistikler(){
kitapService.getKitapTurIstatistikListe().enqueue(object:
Callback<ArrayList<KitapTurIstatistikModel>> {
override fun onFailure(call: Call<ArrayList<KitapTurIstatistikModel>>?, t: Throwable) {
Log.d("Exception",""+t.localizedMessage);
SimpleToast.error(context, resources.getString(R.string.kitapListeHata), "{fa-times-circle}");
pd.dismiss();
}

override fun onResponse(call: Call<ArrayList<KitapTurIstatistikModel>>?, response: Response<ArrayList<KitapTurIstatistikModel>>) {
val liste = response.body() as ArrayList<KitapTurIstatistikModel>;
pieEntry = ArrayList<PieEntry>();
val colorListe = mutableListOf<Int>()
for (l in liste){
pieEntry.add(PieEntry(l.adet!!.toFloat(),l.aciklama));
colorListe.add(ProjectUtil.generateRandomColorCode());
}
val dataSet = PieDataSet(pieEntry, "");
val data = PieData(dataSet);
dataSet.colors = colorListe;
pieChart.data = data;
pieChart.description.text = "";
pieChart.isDrawHoleEnabled = false;
pieChart.invalidate();
data.setValueTextSize(13f);

pd.dismiss();
}
});
}
}

Yukarıda bahsettiğim 2 Recyclerview ve PieChart init metodunda çağırılan aşağıda ki kodlar ile dolmaktadır.

        this.loadSon5Kitap();
this.loadKitapTurleri();
this.loadKitapTurIstatistikler();

Son kaydedilen 5 kitabı gösteren Recyclerview ın layout ve adapterları aşağıda ki gibidir.

dash_card_kitap.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content">

<ImageView
android:id="@+id/dashKitapCardImageId"
android:layout_width="160dp"
android:layout_height="200dp"
android:layout_marginTop="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/edit_text_border" />
</androidx.constraintlayout.widget.ConstraintLayout>

DashKitapAdapter.kt

class DashKitapAdapter(private val mContext: Context, private val kitapListe:ArrayList<KitapModel>):
RecyclerView.Adapter<DashKitapHolder>(){

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DashKitapHolder {
val dashKitapCardView: View = LayoutInflater.from(mContext).inflate(R.layout.dash_card_kitap,parent,false);
return DashKitapHolder(dashKitapCardView);
}

override fun getItemCount(): Int {
return kitapListe.size;
}

override fun onBindViewHolder(holder: DashKitapHolder, position: Int) {
val kitap:KitapModel = kitapListe.get(position);

Glide.with(mContext).load(kitap.kitapResimPath).into(holder.dashKitapImage);
holder.dashKitapImage.setOnClickListener {
putKitapDetayIntoSharedPreferences(mContext,kitap);
ProjectUtil.activityYonlendir(mContext, KitapDetayActivity());
}
}

private fun putKitapDetayIntoSharedPreferences(mContext: Context, kitap: KitapModel) {
kitap.id?.let {
ProjectUtil.putIntDataToSharedPreferences(mContext,ProjectUtil.SHARED_PREF_FILE,"kitapId",
it
)
};
ProjectUtil.putStringDataToSharedPreferences(mContext,ProjectUtil.SHARED_PREF_FILE,"kitapAd",kitap.kitapAd.toString());
ProjectUtil.putStringDataToSharedPreferences(mContext,ProjectUtil.SHARED_PREF_FILE,"yazarAd",kitap.yazarAd.toString());
ProjectUtil.putStringDataToSharedPreferences(mContext,ProjectUtil.SHARED_PREF_FILE,"kitapAciklama",kitap.kitapAciklama.toString());
ProjectUtil.putStringDataToSharedPreferences(mContext,ProjectUtil.SHARED_PREF_FILE,"kitapTur",kitap.kitapTur!!.aciklama.toString());
ProjectUtil.putStringDataToSharedPreferences(mContext,ProjectUtil.SHARED_PREF_FILE,"kitapYayinevi",kitap.yayinEvi!!.aciklama.toString());
ProjectUtil.putStringDataToSharedPreferences(mContext,ProjectUtil.SHARED_PREF_FILE,"kitapResim",kitap.kitapResimPath.toString());
kitap.alinmatarihi?.let { ProjectUtil.formatDate(it,"dd.MM.yyyy") }?.let {
ProjectUtil.putStringDataToSharedPreferences(mContext,ProjectUtil.SHARED_PREF_FILE,"kitapAlinmaTarih",
it
)
};
ProjectUtil.putDoubleDataToSharedPreferences(mContext,ProjectUtil.SHARED_PREF_FILE,"kitapPuan",kitap.kitapPuan);
}
}

Burada dikkat etmemiz gereken şey bu adapter ın setlendiği RecyclerView ' ın genelde kullanılan tarzdan farklı olarak dikey değil yatay durmasıdır. Bu da fragmentta ki aşağıda ki kod satırları ile oluyor.

    val sonKitaplarLayout = LinearLayoutManager(context!!,LinearLayoutManager.HORIZONTAL, false);
    sonEklenenKitaplar.setHasFixedSize(true);
    sonEklenenKitaplar.layoutManager = sonKitaplarLayout;

Kitap türlerini gösteren Recyclerview ın layout ve adapterları aşağıda ki gibidir.

card_dash_kitaptur.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<com.mikhaellopez.circularimageview.CircularImageView
android:id="@+id/dashKitapturImageViewId"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_centerHorizontal="true"
app:civ_border_color="@color/imageShadow"
app:civ_border_width="1dp"
app:civ_shadow="true"
app:civ_shadow_color="@color/imageShadow"
app:civ_shadow_radius="2dp" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/dashKitapturTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_below="@id/dashKitapturImageViewId"
android:layout_centerInParent="true"
android:text="asddsa"
android:textSize="16sp"
android:textStyle="bold" />
</RelativeLayout>

DashKitapturAdapter.kt

class DashKitapturAdapter(private val mContext: Context, private val kitapTurListe:ArrayList<IlgiAlanlariParametreModel>):
RecyclerView.Adapter<DashKitapturHolder>(){

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DashKitapturHolder {
val dashKitapturlerCardView: View = LayoutInflater.from(mContext).inflate(R.layout.card_dash_kitaptur,parent,false);
return DashKitapturHolder(dashKitapturlerCardView);
}

override fun getItemCount(): Int {
return kitapTurListe.size;
}

override fun onBindViewHolder(holder: DashKitapturHolder, position: Int) {
val ilgiAlan:IlgiAlanlariParametreModel = kitapTurListe.get(position);
Glide.with(mContext).load(ilgiAlan.resim).into(holder.dashKitapturImage);
holder.dashKitapturText.text = ilgiAlan.aciklama;
}
}

Soru,istek ve önerilerinizi mesutemrecelenk@gmail.com adresine yazabilirsiniz. Bir sonraki yazıda görüşmek üzere hoşça kalın...

6 Şubat 2021 Cumartesi

Android Kütüphane Sistemi Mobil Uygulaması - 4 (Navigation Menu ve Toolbar)

  Merhabalar. Android Kütüphane Sistemi Mobil Uygulaması yazı dizisinin döndüncü yazısı ile yeniden sizlerleyim. Bu yazıda sisteme giriş yaptıktan sonra görülen Navigation Drawer ve Toolbar componentlerinden bahsedeceğim. Tekrar belirtmekte fayda olacak, uygulamanın kodlarına buradan erişebilirsiniz.

Dashboard ekranı sol menüden (Navigation Drawer Menu) erişilebilen bir fragment olmakla birlikte uygulamayı açınca (tabi login olmuş isek) ilk set edilen fragmenttır. Bu menu MainActivity'de ekleniyor olup tüm eventleri burada verilmektedir. 

Dilerseniz ilk olarak sol menüyü, toolbarı ve fragmentleri içeren MainActivity sınıfımıza bir göz atalım.


MainActivity çalışınca sırasıyla aşağıda ki işlemleri yapar;

    1. İzin kontrolü (Kamera kullanım , dosya okuma-yazma ve internet kullanım izni)

    2.Toolbar ın setlenmesi

    3. Navigation Drawer Menü setlenmesi

işlemlerini yapar. Bu activity'nin layoutu aşağıdaki gibidir.


activity_main.xml

<androidx.drawerlayout.widget.DrawerLayout 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:id="@+id/drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
tools:openDrawer="start">

<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/rootLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/barLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ToolbarTheme">

<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbarNav"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:title=" "
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Kütüphane Sistemi"
android:textColor="@color/whiteTextColor"
android:textSize="16sp"
android:textStyle="bold" />
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
<FrameLayout
android:id="@+id/fragmentNavTutucu"
android:fitsSystemWindows="true"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/kitapEkleBtn"
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="25dp"
android:clickable="true"
app:srcCompat="@drawable/ic_add_24dp" />


<com.github.clans.fab.FloatingActionMenu
android:id="@+id/hizliErisimFabButton"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:paddingRight="25dp"
android:paddingBottom="35dp"
app:menu_labels_style="@style/MenuLabelsStyle"
app:menu_labels_showAnimation="@anim/fab_scale_up"
app:menu_labels_hideAnimation="@anim/fab_scale_down"
app:menu_animationDelayPerItem="1"
app:menu_shadowColor="#444"
android:paddingLeft="10dp"
app:menu_colorRipple="@color/kirmizi"
app:menu_icon="@drawable/ic_directions_run_white_24dp"
app:menu_labels_ellipsize="end"
app:menu_labels_singleLine="true"
app:menu_backgroundColor="#ccffffff"
app:menu_fab_label="@string/hizliErisimMenuLabel">

<com.github.clans.fab.FloatingActionButton
android:id="@+id/kitapListeFabButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/MenuButtonsSmall"
android:src="@drawable/ic_library_books_24dp"
app:fab_size="mini"
app:fab_label="@string/hizliErisimKitapListeLabel" />

<com.github.clans.fab.FloatingActionButton
android:id="@+id/kitapEklemeFabButton"
style="@style/MenuButtonsSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_add_24dp"
app:fab_size="mini"
app:fab_label="@string/hizliErisimKitapEklemeLabel" />

<com.github.clans.fab.FloatingActionButton
android:id="@+id/profilIslemFabButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/MenuButtonsSmall"
android:src="@drawable/ic_person_24dp"
app:fab_size="mini"
app:fab_label="@string/hizliErisimProfilIslemLabel" />

</com.github.clans.fab.FloatingActionMenu>


</androidx.coordinatorlayout.widget.CoordinatorLayout>

<com.google.android.material.navigation.NavigationView
android:id="@+id/navigationView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="@drawable/navigation_background"
app:headerLayout="@layout/kutuphane_sistemi_nav_header_layout"
app:itemIconTint="@color/whiteTextColor"
app:itemBackground="@drawable/navigation_selected_item_background"
app:itemTextAppearance="@style/LeftMenuUiTestTextView"
app:menu="@menu/kutuphane_nav_items"/>
</androidx.drawerlayout.widget.DrawerLayout>


Burada kitap eklemek için bir adet FloatingActionButton ve hızlı menü için ise üçüncü parti bir kütüphane kullandım. Kitap ekleme butonu kitap listesi fragment ı setlenince visible olup sonra önümüzdeki yazılarda bahsedeceğim. 

Hızlı menü için kullandığım componentin detaylarına buradan ulaşabilirsiniz. Bu componenti kullanmak için evvela build.gradle (Module:App) dosyanıza aşağıda ki dependency i eklemeniz gerekmektedir.

                implementation 'com.github.clans:fab:1.6.4'


Bu hızlı menünün açılmış hali aşağıda ki gibidir.


Şimdide bütün bu componentlere, menülere ve toolbarda ki search e nasıl event veridliğini bu layout u içeren activity olan MainActivity yi anlatarak devam edelim.


MainActivity.kt

class MainActivity : AppCompatActivity() {

private lateinit var kullaniciAdSoyad:TextView;
private lateinit var kullaniciResim:ImageView;
private lateinit var tempFragment:Fragment;
private lateinit var kitapService: IKitapIslemService;
private lateinit var pd:Dialog;

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

checkPermissions();

pd = Dialog(this);
val pdView: View = layoutInflater.inflate(R.layout.custom_progress_dialog,null);
pd.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT));
pd.setTitle(null);
pd.setContentView(pdView);
pd.setCancelable(false);
pd.show();

setSupportActionBar(toolbarNav);
val toggle = ActionBarDrawerToggle(this,drawer, toolbarNav as Toolbar?,0,0);
drawer.addDrawerListener(toggle);
toggle.setDrawerIndicatorEnabled(true);
toggle.syncState();

val navHeaderView:View =navigationView.getHeaderView(0);

this.kullaniciAdSoyad = navHeaderView.findViewById(R.id.kullaniciAdSoyadTextView) as TextView;
this.kullaniciResim = navHeaderView.findViewById(R.id.userImage) as ImageView;
kitapService = WebApiUtil.getKitapService(this);

setNavigationHeaderValues(applicationContext,pd);
setFABButtonMenuActions();
if(ProjectUtil.getStringDataFromSharedPreferences(this,ProjectUtil.SHARED_PREF_FILE,"navfragment") != null
&&ProjectUtil.getStringDataFromSharedPreferences(this,ProjectUtil.SHARED_PREF_FILE,"navfragment")
.equals("KitapIslemFragment") ){
ProjectUtil.removeFromSharedPreferences(this,ProjectUtil.SHARED_PREF_FILE,"navfragment");
tempFragment = KitapIslemFragment();
supportFragmentManager.beginTransaction()
.replace(R.id.fragmentNavTutucu,tempFragment).commit();
}else{
hizliErisimFabButton.visibility = View.VISIBLE;
kitapEkleBtn.visibility = View.GONE;
tempFragment = AnasayfaFragment();
supportFragmentManager.beginTransaction()
.replace(R.id.fragmentNavTutucu,tempFragment).commit();
}
navigationView.setNavigationItemSelectedListener {item ->
pd.show();
if(item.itemId == R.id.anasayfaItem){
item.setCheckable(true);
kitapEkleBtn.visibility = View.GONE;
hizliErisimFabButton.visibility = View.VISIBLE;
tempFragment = AnasayfaFragment();
}else if(item.itemId == R.id.kitapIslemlerItem){
hizliErisimFabButton.visibility = View.GONE;
item.setCheckable(true);
tempFragment = KitapIslemFragment();
}else if(item.itemId == R.id.parametreIslemlerItem){
kitapEkleBtn.visibility = View.GONE;
hizliErisimFabButton.visibility = View.GONE;
ProjectUtil.activityYonlendir(this,ParametreActivity());
}else if(item.itemId == R.id.profilIslemlerItem){
item.setCheckable(true);
hizliErisimFabButton.visibility = View.GONE;
kitapEkleBtn.visibility = View.GONE;
tempFragment = ProfilIslemleriFragment();
}else if(item.itemId == R.id.cikisItem){
val ad = AlertDialog.Builder(navigationView.context);
ad.setMessage(resources.getString(R.string.cikisYapmakIstiyormusunuz));
ad.setPositiveButton(resources.getString(R.string.evet)){ dialogInterface, i ->
ProjectUtil.deleteAllSharedPreferencesData(applicationContext,ProjectUtil.SHARED_PREF_FILE);
ProjectUtil.activityYonlendir(applicationContext,LoginActivity());
}

ad.setNegativeButton(resources.getString(R.string.hayir)){dialogInterface, i ->
}

ad.create().show();

}

if(item.itemId != R.id.cikisItem){
supportFragmentManager.beginTransaction()
.replace(R.id.fragmentNavTutucu,tempFragment).commit();
}

pd.dismiss();
drawer.closeDrawer(GravityCompat.START);
true;
}

pd.dismiss();
}

private fun setFABButtonMenuActions() {
kitapListeFabButton.setOnClickListener {
hizliErisimFabButton.toggle(false);
hizliErisimFabButton.visibility = View.GONE;
tempFragment = KitapIslemFragment();
supportFragmentManager.beginTransaction()
.replace(R.id.fragmentNavTutucu,tempFragment).commit();
}

kitapEklemeFabButton.setOnClickListener {
hizliErisimFabButton.toggle(false);
ProjectUtil.activityYonlendir(this, KitapEklemeActivity());
}

profilIslemFabButton.setOnClickListener {
hizliErisimFabButton.toggle(false);
hizliErisimFabButton.visibility = View.GONE;
tempFragment = ProfilIslemleriFragment();
supportFragmentManager.beginTransaction()
.replace(R.id.fragmentNavTutucu,tempFragment).commit();
}
}

private fun checkPermissions() {
var camPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if(camPermission != PackageManager.PERMISSION_GRANTED){//İzin aktif edilmemişse
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),12345);
}

camPermission = ContextCompat.checkSelfPermission(this,Manifest.permission.READ_EXTERNAL_STORAGE);
if(camPermission != PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),54321);
}

camPermission = ContextCompat.checkSelfPermission(this,Manifest.permission.INTERNET);
if(camPermission != PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.INTERNET),100);
}
}

override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.kutuphane_toolbar_head_menu,menu);
val searchItem:MenuItem = menu.findItem(R.id.app_bar_search);
val searchView:SearchView = searchItem.actionView as SearchView;
searchView.queryHint = resources.getString(R.string.araHeaderLabel);

searchView.findViewById<AutoCompleteTextView>(R.id.search_src_text).threshold = 2;

searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean {
return false
}

override fun onQueryTextChange(query: String?): Boolean {
if(query?.length!! >2){
var liste:ArrayList<KitapModel> = ArrayList<KitapModel>();
val jsonObj: JSONObject = JSONObject();
jsonObj.put("kitapAd",query);
jsonObj.put("yazaarAd",query);
kitapService.getKitapListe(jsonObj.toString()).enqueue(object:
Callback<ArrayList<KitapModel>> {
override fun onFailure(call: Call<ArrayList<KitapModel>>?, t: Throwable) {
SimpleToast.error(applicationContext, resources.getString(R.string.kitapListeHata), "{fa-times-circle}");
}

override fun onResponse(call: Call<ArrayList<KitapModel>>?, response: Response<ArrayList<KitapModel>>) {
if(response.body() != null){
liste = response.body() as ArrayList<KitapModel>;
searchView.findViewById<AutoCompleteTextView>(R.id.search_src_text).setAdapter(KitapFiltreAdapter(applicationContext,R.layout.kitap_search_item_layout,liste));
}
}
});
}

return true;
}
})


return true;
}



private fun setNavigationHeaderValues(c:Context,pd:Dialog){
this.kullaniciAdSoyad.text = resources.getString(R.string.hosGeldiniz)+ProjectUtil.getStringDataFromSharedPreferences(c,ProjectUtil.SHARED_PREF_FILE,"adSoyad");
this.getKullaniciResim(c,pd,this.kullaniciResim);
}

private fun getKullaniciResim(
applicationContext: Context,
pd: Dialog,
kullaniciResim: ImageView
) {
val kullaniciService: IKullaniciService = WebApiUtil.getKullaniciService(applicationContext);
kullaniciService.getKullaniciResim().enqueue(object: Callback<KullaniciResimModel> {
override fun onFailure(call: Call<KullaniciResimModel>?, t: Throwable) {
SimpleToast.error(applicationContext, resources.getString(R.string.resimGetirmeHata), "{fa-times-circle}");
pd.dismiss();
}

override fun onResponse(call: Call<KullaniciResimModel>?, response: Response<KullaniciResimModel>) {
val kullaniciResimModel: KullaniciResimModel = response.body() as KullaniciResimModel;
kullaniciResim.setImageBitmap(ProjectUtil.getBitmapResourceFromBase64(kullaniciResimModel.userImageBase64));
pd.dismiss();
}
});
}

override fun onBackPressed() {
val ad = AlertDialog.Builder(navigationView.context);
ad.setMessage(resources.getString(R.string.kapatmakIstiyormusunuz));
ad.setPositiveButton(resources.getString(R.string.evet)){ dialogInterface, i ->
finishAffinity();
}

ad.setNegativeButton(resources.getString(R.string.hayir)){dialogInterface, i ->
}

ad.create().show();
}
}

Burada ki en temel işlem gerek hızlı menüden yapılan seçimde gerek navigation menüden yapılan seçimde FrameLayout'a aşağıda ki kod ile gerekli fragment ın setlenme işlemidir.

supportFragmentManager.beginTransaction()
.replace(R.id.fragmentNavTutucu,tempFragment).commit();


Bir diğer işlem ise onCreateOptionsMenu metodunda yapılan auto complete search işlemidir. Toolbarda ki inputtext'e yazar adı ya da kitap adı yazdığımız zaman servisten sonuçları alıp custom bir formatta sonuç gösteriyorum. Bu format custom bir format olduğu için bir adapter ve bu adapter da inflate edilen bir layout a sahiptir. Gelen sonuça tıklandığı zaman ise seçilen kitabın detayı açılmaktadır. Dilerseniz adapter kodlarına bakalım.

KitapFiltreAdapter.kt

class KitapFiltreAdapter(context:Context,
@LayoutRes private val layoutRes:Int,
val kitapListe:ArrayList<KitapModel>):ArrayAdapter<KitapModel>(context,layoutRes,kitapListe){

private val inflater: LayoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater;

override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val view: View;
view = inflater.inflate(layoutRes, parent, false);

val kitapImage:ImageView = view.findViewById(R.id.searchItemImageId) as ImageView;
val kitapAdTw:TextView = view.findViewById(R.id.searchKitapAdItemId) as TextView;
val yazarAdTw:TextView = view.findViewById(R.id.searchKitapYazarAdItemId) as TextView;
val mainLayout:ConstraintLayout = view.findViewById(R.id.mainSearchLayout);
val kitap:KitapModel = getItem(position) as KitapModel;

Glide.with(context).load(kitap.kitapResimPath).into(kitapImage);
if(kitap.kitapAd!!.length>24){
kitapAdTw.text = kitap.kitapAd!!.substring(0,23)+"...";
}else{
kitapAdTw.text = kitap.kitapAd;
}

yazarAdTw.text = kitap.yazarAd;

mainLayout.setOnClickListener {
putKitapDetayIntoSharedPreferences(context,kitap);
ProjectUtil.activityYonlendir(context,KitapDetayActivity());
}

return view;
}

override fun getItem(position: Int): KitapModel? {
return kitapListe.get(position);
}

private fun putKitapDetayIntoSharedPreferences(mContext: Context, kitap: KitapModel) {
kitap.id?.let {
ProjectUtil.putIntDataToSharedPreferences(mContext,ProjectUtil.SHARED_PREF_FILE,"kitapId",
it
)
};
ProjectUtil.putStringDataToSharedPreferences(mContext,
ProjectUtil.SHARED_PREF_FILE,"kitapAd",kitap.kitapAd.toString());
ProjectUtil.putStringDataToSharedPreferences(mContext,
ProjectUtil.SHARED_PREF_FILE,"yazarAd",kitap.yazarAd.toString());
ProjectUtil.putStringDataToSharedPreferences(mContext,
ProjectUtil.SHARED_PREF_FILE,"kitapAciklama",kitap.kitapAciklama.toString());
ProjectUtil.putStringDataToSharedPreferences(mContext,
ProjectUtil.SHARED_PREF_FILE,"kitapTur",kitap.kitapTur!!.aciklama.toString());
ProjectUtil.putStringDataToSharedPreferences(mContext,
ProjectUtil.SHARED_PREF_FILE,"kitapYayinevi",kitap.yayinEvi!!.aciklama.toString());
ProjectUtil.putStringDataToSharedPreferences(mContext,
ProjectUtil.SHARED_PREF_FILE,"kitapResim",kitap.kitapResimPath.toString());
kitap.kayittarihi?.let { ProjectUtil.formatDate(it,"dd.MM.yyyy") }?.let {
ProjectUtil.putStringDataToSharedPreferences(mContext, ProjectUtil.SHARED_PREF_FILE,"kitapAlinmaTarih",
it
)
};
ProjectUtil.putDoubleDataToSharedPreferences(mContext,ProjectUtil.SHARED_PREF_FILE,"kitapPuan",kitap.kitapPuan);
}

}

Burada URL den resmi direk göstermek için Glide kütüphanesinden faydalandım. Bu kütüphaneyi kullanmak için build.gradle (Module:App) dosyanıza aşağıda ki dependency i eklemeniz gerekmektedir.

         implementation 'com.github.bumptech.glide:glide:4.6.1'   

Bu adapter da inflate edilen layout ise aşağıda ki gibidir.

kitap_search_item_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/mainSearchLayout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/whiteTextColor">


<ImageView
android:id="@+id/searchItemImageId"
android:layout_width="106dp"
android:layout_height="102dp"
android:layout_marginTop="5dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/edit_text_border" />

<TextView
android:id="@+id/searchKitapAdItemId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="TextView"
android:textAllCaps="false"
android:textColor="@color/siyah"
android:textSize="14sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/searchItemImageId"
app:layout_constraintTop_toTopOf="parent" />

<TextView
android:id="@+id/searchKitapYazarAdItemId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:text="TextView"
android:textSize="12sp"
android:textStyle="italic"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/searchItemImageId"
app:layout_constraintTop_toBottomOf="@+id/searchKitapAdItemId" />

<View
android:id="@+id/view"
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_marginTop="1dp"
android:background="@color/imageShadow"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/searchItemImageId" />

</androidx.constraintlayout.widget.ConstraintLayout>

Burada yapılan search sonuçları ise aşağıda ki gibi listelenir.


Soru,istek ve önerilerinizi mesutemrecelenk@gmail.com adresine yazabilirsiniz. Bir sonraki yazıda görüşmek üzere hoşça kalın...