App mit zwei Toolbars

  • Antworten:5
  • Bentwortet
Robbiani Renato
  • Forum-Beiträge: 609

30.01.2023, 20:41:38 via Website

Hallo zusammen

Meine App hat auf dem Mainlayout eine Toolbar und ein Fragment. Im Fragment selber möchte ich ebenfalls eine Toolbar einsetzen. Ich frage mich ob das überhaupt geht weil die App nur abstürzt.

Fragment mit Toolbar:

package ch.robbisoft.klassennotfall

import android.app.ActionBar.LayoutParams
import android.app.Activity
import android.content.DialogInterface
import android.content.Intent
import android.graphics.Color
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageButton
import android.widget.LinearLayout
import android.widget.TextView
import android.widget.Toast
import android.widget.Toolbar
import androidx.activity.result.contract.ActivityResultContracts
import java.lang.Exception

private val TAG = FragKlasseA::class.simpleName

// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"

private const val DATEI = "tel"
private const val DATNAME = "namena"
private const val DATMUTTER = "muttera"
private const val DATVATER = "vatera"
private const val DATALLG = "allga"

private const val HOCH = 50
private const val TEXTHOCH = 20f

/**
* A simple [Fragment] subclass.
* Use the [FragKlasseA.newInstance] factory method to
* create an instance of this fragment.
*/
class FragKlasseA : Fragment(), DialogInterface.OnClickListener {
// TODO: Rename and change types of parameters
private var param1: String? = null
private var param2: String? = null
private var aktuell = 0 //Gibt die Aktuelle Position an
private var aname = arrayListOf()
private var amutter = arrayListOf()
private var avater = arrayListOf()
private var aallg = arrayListOf()

private lateinit var frage : DialogFrag

private lateinit var obj_toolbar : Toolbar
private lateinit var obj_adda : ImageButton
private lateinit var obj_savea : ImageButton

private lateinit var obj : View

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    arguments?.let {
        param1 = it.getString(ARG_PARAM1)
        param2 = it.getString(ARG_PARAM2)
    }
    loaddate()
}

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                          savedInstanceState: Bundle?): View? {
    // Inflate the layout for this fragment
    val view = inflater.inflate(R.layout.frag_klasse_a, container, false)
    obj = view

    build(obj)
    //Toolbar anlegen
    obj_toolbar = obj.findViewById(R.id.to_bara)

// setSupportActionBar(obj_toolbar)
obj_toolbar.inflateMenu(R.menu.mnu_frac)

    //Person hinzufühgen
    obj_adda = view.findViewById(R.id.imgb_plusa)
    obj_adda.setOnClickListener {
        val intent = Intent(context, PersonIn::class.java)
        personainhorcher.launch(intent)
    }

    //Datem speichern
    obj_savea = view.findViewById(R.id.imgb_savea)
    obj_savea.setOnClickListener {
        savedate()
        Toast.makeText(context, this.getString(R.string.lbl_meldungspeicher), Toast.LENGTH_SHORT).show()
    }

    return view
}

//person in Liste aufnehmen
var personainhorcher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()){ result ->
    if(result.resultCode == Activity.RESULT_OK) {
        if (result.data != null) {
            val data: Intent? = result.data
            val pers = Person()
            if (data != null) {
                pers.pname = data.getStringExtra("name").toString()
                pers.telmutter = data.getStringExtra("mutter").toString()
                pers.telvater = data.getStringExtra("vater").toString()
                pers.telalg = data.getStringExtra("allg").toString()
                aname.add(pers.pname)
                amutter.add(pers.telmutter)
                avater.add(pers.telvater)
                aallg.add(pers.telalg)
                savedate()
                rebuild(obj)
            }
        }
    }
}
//Person in Liste bearbeiten
var personaworkhorcher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()){ result ->
    if(result.resultCode == Activity.RESULT_OK){
        if(result.data != null){
            val daten : Intent? = result.data
            if(daten != null){
                val person = Person()
                person.pname = daten.getStringExtra("name").toString()
                person.telmutter = daten.getStringExtra("mutter").toString()
                person.telvater = daten.getStringExtra("vater").toString()
                person.telalg = daten.getStringExtra("allg").toString()
                aname[aktuell] = person.pname
                amutter[aktuell] = person.telmutter
                avater[aktuell] = person.telvater
                aallg[aktuell] = person.telalg
                savedate()
                rebuild(obj)
            }
        }
    }
}

companion object {
    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment FragKlasseA.
     */
    // TODO: Rename and change types and number of parameters
    @JvmStatic
    fun newInstance(param1: String, param2: String) =
        FragKlasseA().apply {
            arguments = Bundle().apply {
                putString(ARG_PARAM1, param1)
                putString(ARG_PARAM2, param2)
            }
        }
}

override fun onClick(dialog: DialogInterface?, was: Int) {
    when( was ){
        -1 -> {
            //Einträge Löschen
            aname.removeAt(aktuell)
            amutter.removeAt(aktuell)
            avater.removeAt(aktuell)
            aallg.removeAt(aktuell)
            savedate()
            Toast.makeText(context, this.getString(R.string.lbl_meldungdelete), Toast.LENGTH_SHORT).show()
            rebuild(obj)
        }
        -3 -> {
            //Personendaten an PersonIn Activity senden
            val param = Intent(context, PersonIn::class.java)
            param.putExtra("name", aname.get(aktuell))
            param.putExtra("telmutter", amutter.get(aktuell))
            param.putExtra("telvater", avater.get(aktuell))
            param.putExtra("telalg", aallg.get(aktuell))
            //Activity aufrufen
            personaworkhorcher.launch(param)
        }
    }
}

fun savedate(){
    val speicher = Speicher(requireContext())
    speicher.speichern(aname, DATEI, DATNAME)
    speicher.speichern(amutter, DATEI, DATMUTTER)
    speicher.speichern(avater, DATEI, DATVATER)
    speicher.speichern(aallg, DATEI, DATALLG)
}

fun loaddate(){
    val speicher = Speicher(requireContext())
    try {
        aname = speicher.laden(DATEI, DATNAME)!!
        amutter = speicher.laden(DATEI, DATMUTTER)!!
        avater = speicher.laden(DATEI, DATVATER)!!
        aallg = speicher.laden(DATEI, DATALLG)!!
    }catch (e : Exception){
        Log.e(TAG, e.message.toString())
    }
}

fun rebuild(view : View){
    var lay_tab : LinearLayout
    lay_tab = view.findViewById(R.id.lay_atabelle)
    lay_tab.removeAllViews()
    build(view)
}

fun build(view : View){
    var lay_tab : LinearLayout
    lay_tab = view.findViewById(R.id.lay_atabelle)
    //Attribute definieren
    var param = LinearLayout.LayoutParams(0, LayoutParams.WRAP_CONTENT, 1f)
    //maximal Einträge bestimmen
    val max = aname.size
    //Liste aufbauen
    for(pos in 0 until max){
        //Anhangpunkt bestimmen
        var tabrow = LinearLayout(view.context)
        tabrow.orientation = LinearLayout.HORIZONTAL
        //Punkt hinzu fügen
        lay_tab.addView(tabrow)
        //Textfelder erstellen und hinzufügen
        var feld_name = TextView(view.context)
        feld_name.layoutParams = param
        feld_name.setSingleLine(true)
        feld_name.setOnClickListener {
            Toast.makeText(view.context, view.context.getString(R.string.lbl_rufename, aname.get(pos)), Toast.LENGTH_LONG).show()
        }
        feld_name.setOnLongClickListener {
            val str_name = aname.get(pos)
            if(str_name.length > 0) {
                aktuell = pos
                frage = DialogFrag()
                frage.persname = str_name
                frage.show(childFragmentManager, DialogFrag.TAG)
            }
            true
        }
        tabrow.addView(feld_name)
        feld_name.setText(aname.get(pos))
        feld_name.setTextSize(TEXTHOCH)

        var feld_mutter = TextView(view.context)
        feld_mutter.layoutParams = param
        feld_mutter.setSingleLine(true)
        feld_mutter.setOnClickListener {
            val text = amutter.get(pos)
            if(text.length > 0) {
                val telefon = Telefon(requireContext())
                telefon.rufen(text)
            }
        }
        feld_name.setOnLongClickListener {
            val str_name = aname.get(pos)
            aktuell = pos
            frage = DialogFrag()
            frage.persname = str_name
            frage.show(childFragmentManager, DialogFrag.TAG)
            true
        }
        tabrow.addView(feld_mutter)
        feld_mutter.setText(amutter.get(pos))
        feld_mutter.setTextSize(TEXTHOCH)

        var feld_vater = TextView(view.context)
        feld_vater.layoutParams = param
        feld_vater.setSingleLine(true)
        feld_vater.setOnClickListener {
            val text = avater.get(pos)
            if(text.length > 0) {
                val telefon = Telefon(requireContext())
                telefon.rufen(text)
            }
        }
        feld_vater.setOnLongClickListener {
            val str_name = aname.get(pos)
            aktuell = pos
            frage = DialogFrag()
            frage.persname = str_name
            frage.show(childFragmentManager, DialogFrag.TAG)
            true
        }
        tabrow.addView(feld_vater)
        feld_vater.setText(avater.get(pos))
        feld_vater.setTextSize(TEXTHOCH)
        feld_vater.setTextColor(Color.BLUE)

        var feld_allg = TextView(view.context)
        feld_allg.layoutParams = param
        feld_allg.setSingleLine(true)
        feld_allg.setOnClickListener {
            val text = aallg.get(pos)
            if(text.length > 0) {
                val telefon = Telefon(requireContext())
                telefon.rufen(text)
            }
        }
        feld_allg.setOnLongClickListener {
            val str_name = aname.get(pos)
            aktuell = pos
            frage = DialogFrag()
            frage.persname = str_name
            frage.show(childFragmentManager, DialogFrag.TAG)
            true
        }
        tabrow.addView(feld_allg)
        feld_allg.setText(aallg.get(pos))
        feld_allg.setTextSize(TEXTHOCH)
    }
}

}

Die App startet nicht. An der Stelle "obj_toolbar = obj.findViewById(R.id.to_bara)" kommt folgender Fehler:

2023-01-30 20:27:05.107 11820-11820/ch.robbisoft.klassennotfall E/AndroidRuntime: FATAL EXCEPTION: main
Process: ch.robbisoft.klassennotfall, PID: 11820
java.lang.ClassCastException: androidx.appcompat.widget.Toolbar cannot be cast to android.widget.Toolbar
    at ch.robbisoft.klassennotfall.FragKlasseA.onCreateView(FragKlasseA.kt:78)

Nun frage ich mich ob das überhaupt geht?

Ebenfalls kann ich die Zeile "setSupportActionBar(obj_toolbar)" nicht ausführen. Möglicher weise sitze ich auf dem falschen Dampfer.

Die Main Klasse

package ch.robbisoft.klassennotfall

import android.Manifest
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.TextView
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.widget.Toolbar
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.preference.PreferenceManager
import androidx.viewpager2.widget.ViewPager2
import ch.robbisoft.klassennotfall.databinding.ActivityMainBinding
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayoutMediator

private val TAG = MainActivity::class.simpleName

class MainActivity : AppCompatActivity(), View.OnClickListener {

var rechte = arrayOf(
    Manifest.permission.WRITE_EXTERNAL_STORAGE,
    Manifest.permission.READ_EXTERNAL_STORAGE
)
private var str_text: String? = null

private lateinit var binding : ActivityMainBinding
private lateinit var tabs : TabLayout
private lateinit var page : ViewPager2
private lateinit var toolbar: Toolbar
private lateinit var ctx : Context
private lateinit var ac_ctx : Context
private lateinit var klassnama : String
private lateinit var klassnamb : String
private lateinit var klassnamc : String

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ActivityMainBinding.inflate(layoutInflater)
    val view = binding.root
    setContentView(view)

    ctx = applicationContext
    ac_ctx = this

    val prefs = PreferenceManager.getDefaultSharedPreferences(ac_ctx)
    if(!prefs.contains("key_eins")){
        val prefvalue = prefs.edit()
        klassnama = getString(R.string.lbl_tab_eins)
        klassnamb = getString(R.string.lbl_tab_zwei)
        klassnamc = getString(R.string.lbl_tab_drei)
        prefvalue.putString("key_eins", klassnama)
        prefvalue.putString("key_zwei", klassnamb)
        prefvalue.putString("key_drei", klassnamc)
        prefvalue.apply()
        prefvalue.commit()
    }else{
        klassnama = prefs.getString("key_eins", null).toString()
        klassnamb = prefs.getString("key_zwei", null).toString()
        klassnamc = prefs.getString("key_drei", null).toString()
    }


    val KlassArray = arrayOf<String>(
        klassnama,
        klassnamb,
        klassnamc
    )

    toolbar = binding.tobBar
    setSupportActionBar(toolbar)

    toolbar.inflateMenu(R.menu.menu_main)
    tabs = binding.tabLaytop
    page = binding.laySeite

    tabs.addTab(tabs.newTab().setText(klassnama))
    tabs.addTab(tabs.newTab().setText(klassnamb))
    tabs.addTab(tabs.newTab().setText(klassnamc))
    tabs.tabGravity = TabLayout.GRAVITY_FILL

    val adapter = MyAdapter(supportFragmentManager, lifecycle)
    adapter.counter = tabs.tabCount
    page.adapter = adapter

    TabLayoutMediator(tabs, page) { tab, position ->
        tab.text = KlassArray[position].toString()
    }.attach()

    tabs.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener{
        override fun onTabSelected(tab: TabLayout.Tab?) {
            if (tab != null) {
                page.currentItem = tab.position
            }
        }

        override fun onTabUnselected(tab: TabLayout.Tab?) {

        }

        override fun onTabReselected(tab: TabLayout.Tab?) {

        }

    })

    page.setOnClickListener {
        val objekt = it as TextView
        val text = objekt.text.toString()
        Log.d(TAG, text)
    }

    page.setOnContextClickListener(View.OnContextClickListener { v : View ->
        val objekt = v as TextView
        val text = objekt.text.toString()
        Log.d(TAG, text)
        return@OnContextClickListener true
    })

    //prüft ob OS Version > 6 ist, denn vorher kann nicht geprüft werden

// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { //prüfen ob Rechte vorhanden sind
if (pruefrechte()) {
str_text = getString(R.string.lbl_recht_neu)
Toast.makeText(ctx, str_text, Toast.LENGTH_SHORT).show()
//Code für die Initialisierung
} else {
str_text = getString(R.string.lbl_recht_fasch)
Toast.makeText(ctx, str_text, Toast.LENGTH_SHORT).show()
finish()
}
// } else {
// str_text = getString(R.string.lbl_recht_alt)
// Toast.makeText(ctx, str_text, Toast.LENGTH_SHORT).show()
// }

}

private fun pruefrechte(): Boolean {
    var result: Int
    val listPermissionsNeeded: MutableList<String> = ArrayList<String>()
    for (p in rechte) {
        result = ContextCompat.checkSelfPermission(this, p)
        if (result != PackageManager.PERMISSION_GRANTED) {
            listPermissionsNeeded.add((p))
        }
    }
    if (!listPermissionsNeeded.isEmpty()) {
        ActivityCompat.requestPermissions(this, (listPermissionsNeeded.toTypedArray() as Array<String?>;), MULTIPLE_PERMISSIONS)
        // keine permissions gesetzt
        return false
    }
    // alle permissions gesetzt
    return true
}

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    when (requestCode) {
        MULTIPLE_PERMISSIONS -> {
            if (grantResults.size > 0) {
                var permissionsDenied = ""
                for (per in permissions) {
                    if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
                        permissionsDenied += "\n" + per
                    }
                }
                // Nach dem ersten Male
            }
            return
        }
    }
}

companion object {
    const val MULTIPLE_PERMISSIONS = 99
}

override fun onCreateOptionsMenu(menu: Menu?): Boolean {
    menuInflater.inflate(R.menu.menu_main, menu)
    return super.onCreateOptionsMenu(menu)
}

override fun onClick(v: View?) {
    var objekt = v as TextView
    var text = objekt.text.toString()
    Log.d(TAG, "->MainActivity " + text)
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    val was = item.itemId
    return when(was){
        R.id.mnu_add -> {
            val intent = Intent(ac_ctx, PersonIn::class.java)
            persinHorcher.launch(intent)
            return true
        }
        R.id.mnu_save -> {
            return true
        }
        R.id.mnu_optionen -> {
            val intent = Intent(ac_ctx, SettingsActivity::class.java)
            OptionenHorcher.launch(intent)
            return true
        }
        else -> super.onOptionsItemSelected(item)
    }
}

var OptionenHorcher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()){ result ->
    if(result.resultCode == Activity.RESULT_OK){
        val prefs = PreferenceManager.getDefaultSharedPreferences(ac_ctx)
        klassnama = prefs.getString("key_eins", null).toString()
        klassnamb = prefs.getString("key_zwei", null).toString()
        klassnamc = prefs.getString("key_drei", null).toString()
        var page : TabLayout.Tab
        page = tabs.getTabAt(0)!!
        page.setText(klassnama)
        page = tabs.getTabAt(1)!!
        page.setText(klassnamb)
        page = tabs.getTabAt(2)!!
        page.setText(klassnamc)
    }
}

var persinHorcher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()){ result ->
    if (result.resultCode == Activity.RESULT_OK){
        if (result.data != null){
            val data : Intent? = result.data
            var pers = Person()
            pers.pname = data!!.getStringExtra("name").toString()
            pers.telmutter = data.getStringExtra("mutter").toString()
            pers.telvater = data.getStringExtra("vater").toString()
            pers.telalg = data.getStringExtra("allg").toString()
        }
    }
}

override fun onPrepareOptionsMenu(menu: Menu?): Boolean {
    return super.onPrepareOptionsMenu(menu)
}

}

Gruss Renato

Kommentieren
Beste Antwort
Jokel
  • Forum-Beiträge: 1.530

12.02.2023, 17:41:07 via Website

Hallo
onCreateOptionsMenu ist seit API 28 deprecated im Fragment.
Benutze dazu das Interfase MenuProvider.

Und die beiden Methoden
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater)
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {

In der onViewCreate
Benutzt du das
activity?.addMenuProvider(this, viewLifecycleOwner, Lifecycle.State.RESUMED)

https://www.youtube.com/watch?v=xPzI0EPP07g

— geändert am 12.02.2023, 17:49:12

Hilfreich?
Kommentieren
Robbiani Renato
  • Forum-Beiträge: 609

30.01.2023, 21:30:47 via Website

Hallo zusammen

Mit dem Absturz bin ich weiter gekommen. Ich habe folgenden Import gemacht.

import androidx.appcompat.widget.Toolbar

Nun läuft die App aber die Menüitem gehen ins lehre. Ich kann sie anklicken, aber geschehen tut nichts.
Wahrscheinlich liegt es doch an der folgenden Zeile die man nicht ausführen kann.

setSupportActionBar(obj_toolbar)

Gruss Renato

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.530

31.01.2023, 05:44:25 via Website

Im Fragment selber möchte ich ebenfalls eine Toolbar einsetzen

Wozu das? Du kannst doch im Fragment das Menue und auch die Icon von der Toolbar in der activity bearbeiten.

Hilfreich?
Kommentieren
Robbiani Renato
  • Forum-Beiträge: 609

11.02.2023, 16:46:48 via Website

Ciao Jokel

Das klingt verlockend. Genau so möchte ich es machen.
Ich habe einiges versucht, aber irgendwo bin ich immer gescheitert. Kannst du mir Zeigen wie ich vorgehen muss damit es funktioniert.

mit folgendem Code welcher ich aus der MainActivity aufrufe komme ich auch nicht weiter.

var aktiv = tabs.get(tabs.indexOfChild(tabs))

"tabs" sind meine Fragmente.

Gruss Renato

Hilfreich?
Kommentieren
Beste Antwort
Jokel
  • Forum-Beiträge: 1.530

12.02.2023, 17:41:07 via Website

Hallo
onCreateOptionsMenu ist seit API 28 deprecated im Fragment.
Benutze dazu das Interfase MenuProvider.

Und die beiden Methoden
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater)
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {

In der onViewCreate
Benutzt du das
activity?.addMenuProvider(this, viewLifecycleOwner, Lifecycle.State.RESUMED)

https://www.youtube.com/watch?v=xPzI0EPP07g

— geändert am 12.02.2023, 17:49:12

Hilfreich?
Kommentieren
Robbiani Renato
  • Forum-Beiträge: 609

13.02.2023, 21:24:45 via Website

Danke Jokel

Lösung mit Film, einfach genial! Nun funktioniert es.

Gruss Renato

Hilfreich?
Kommentieren