Woher soll die Liste wissen woher die Daten herkommen?
Woher soll sie wissen in welche TD Tabelle , Welche DB … sie bearbeiten soll?
Na ja, wenn die Liste über ein Data-Model mit DB-Bindung aufgebaut ist sollten eigentlich alle Daten wie ID usw. bekannt sein.
Ich sehe es so, es ist halt von Google (bzw. Oracle mit JAVA) noch nicht realisiert !!
Beiträge von VomDorf
-
-
OK, danke, das hat mir geholfen.
verstehe zwar nicht, was es bringt ,wenn nur in der View gelöscht wird und nicht parallel in der DB, muss ich ja dann zusätzlich machen, obwohl ich mit dem Model arbeite.
Ich lösche bis jetzt immer erst in der Datenbank und lade dann die View neu. Die View-Befehle (wie remove) ergeben für mich bei der Verwendung einer Datenbank dann keinen Sinn, oder .. !?
-
Hallo,
wahrscheinlich eine dumme Frage.
Man arbeitet bei der Recyclerview sinnvoller Weise mit einem Datamodel.
1. Wenn ich im ViewAdapter z.B. mList.remove(model) realisiere, wird dann parallel der Datensatz in der Datenbank anhand der ID gelöscht ?
2. Kann ich ein mList.remove(model) z.B. auch in der MainActivity ausführen ? (wenn ja denke ich über den Aufruf einer Methode im ViewAdapter, die remove realisiert ?).
Ich würde mir eine Menge Dateiarbeit sparen, wenn parallel die Database verarbeitet wird.
Danke Wolfgang
-
habe die Dateiarbeit nun doch hinbekommen, jetzt kann ich auch eine von der Tabelle festgelegte Zeile markieren !!
Leider muss ich immer erst ein Thema veröffentlichen bis mir selbst die Ideen kommen ......
-
Hallo, eine gewählte Zeile farblich gestalten funktioniert.
Ich benötige aber auch die Möglichkeit, je Tab-Wahl die unterschiedlichsten Zeilen farblich zu gestalten.
Ich bekomme im ViewAdapter , wo ich auch die Select-Farbe setze, keine Dateiarbeit hin.
Hat jemand einen Tipp ?
Code
Alles anzeigenpublic ViewAdapter(Context context, ArrayList<DataModell_TasksView> dataModell_TaskList, MyClickListener myClickListener ) { this.myClickListener = myClickListener; this.context = this.context; this.dataModell_TaskList = dataModell_TaskList; } public interface MyClickListener { void onItemClick(int position, Integer _id); } public void setOnClickListener(View.OnClickListener callback) { myClickListener = (MyClickListener) callback; } @NonNull @Override public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { Context context = parent.getContext(); LayoutInflater inflater = LayoutInflater.from(context); View rowlayout = inflater.inflate(R.layout.list_row, parent, false); MyViewHolder viewHolder = new MyViewHolder(rowlayout); viewHolder.itemView.setOnClickListener((new View.OnClickListener() { @SuppressLint("SuspiciousIndentation") @Override public void onClick(View v) { //Position bestimmen position = viewHolder.getBindingAdapterPosition(); selectedPosition=position; if (myClickListener != null) { isClicked = true; myClickListener.onItemClick(position, dataModell_TaskList.get(position)._id); notifyDataSetChanged(); } } })); return viewHolder; } @Override public void onBindViewHolder(@NonNull MyViewHolder holder, @SuppressLint("RecyclerView") int position) { holder.bereichs_txt.setText(String.valueOf(dataModell_TaskList.get(position).getBereich())); holder.aufgabentyp_txt.setText(String.valueOf(dataModell_TaskList.get(position).getAufgaben())); holder.notiz_txt.setText(String.valueOf(dataModell_TaskList.get(position).getNotiz())); holder.termin_txt.setText(String.valueOf(dataModell_TaskList.get(position).getTermin())); holder.bearbeitet_txt.setText(String.valueOf(dataModell_TaskList.get(position).getBearbeitet())); // holder.itemView.setBackgroundColor(Color.parseColor("#efffff")); // Selected Zeile farblich kennzeichnen if (position == selectedPosition) { holder.itemView.setBackgroundColor(Color.parseColor("#d0cfcf")); } else { holder.itemView.setBackgroundColor(Color.parseColor("#ffffff")); } } @Override public int getItemCount() { return dataModell_TaskList.size(); } public static class MyViewHolder extends RecyclerView.ViewHolder { TextView bereichs_txt, aufgabentyp_txt, notiz_txt, termin_txt, bearbeitet_txt; public MyViewHolder(final View itemView) { super(itemView); bereichs_txt = itemView.findViewById(R.id.TextView_bereich_liste); aufgabentyp_txt = itemView.findViewById(R.id.TextView_aufgabentyp_liste); notiz_txt = itemView.findViewById(R.id.TextView_notiz_liste); termin_txt = itemView.findViewById(R.id.TextView_termin_liste); bearbeitet_txt = itemView.findViewById(R.id.TextView_bearbeitet_liste); } }
-
Problem gelöst, im FragmentStateAdapter den getItemCount richtig angepasst. Dieser sollte die Anzahl der möglichen Views , Fragments wiedergeben.
Bei mir gibt es soviel RecyclerViews wie Datensätze inder "tabtable". Alle Tabs können flexibel bearbeitet werden, d.h. neu, löschen ändern !
Code
Alles anzeigenpublic TabAdapter(@NonNull FragmentActivity fm, int position) { super(fm); this.position = position; myDB = new DBHelper(fm.getApplicationContext()); sSQL = "SELECT * FROM tabtable "; cOrt = myDB.doSQL(sSQL); if ( cOrt != null) { dataCount = cOrt.getCount(); // alle möglichen Tabs der zweiten Reihe, jeder obere Tab hat andere Tabs inder zweiten Tabreihe } else { dataCount=50; // nur zur Sicherheit } }
-
-
Hallo,
in meiner APP gibt es zwei TAB-Reihen. Die erste (obere) bestimmt den Inhalt der zweiten Tab-Reihe (siehe Foro). Über eine mainActivity wird ein Fragment gestartet welches dann eine View erzeugt. Je nach Tab-Konstellation wird eigentlich immer das gleiche Frag,ment gestartet. Solnage ich mich nur in der zweiten Tab-Ebene befinde ist alles OK. Selbst in der ersten Tab-Ebene kann ich vorwärts gehen. Aber wenn ich in der obersten Ebene mindestens einen Tab zurück gehe, wird keine View mehr gebildet ??? Ich vermute, daß die ersten Fragmwnts immer noch aktiv sind, deshalb nicht neu geladcen werden. Aber wie kann ich diese wieder aktivieren , oder liege ich vollkommen falsch ?
So richtig verstehe ich die Rolle der FragmentActivity wahrscheinlich nicht, ohne Inhalt stürzt das Programm ab.
Code
Alles anzeigen...... public class MainActivity extends AppCompatActivity { TabLayout tabLayout; TabLayout tabChef; TabLayout tabBar; ViewPager2 viewPager2; public String tag; final static String MY_DB_NAME = "checktaskdb"; final static String MY_DB_TABLE = "aufgabenliste"; final static String MY_DB_historytable = "history"; final static String MY_DB_tabtable = "tabtable"; final static String MY_DB_aufgabentable = "aufgaben_table"; final static String MY_DB_bereichstable = "bereiche_table"; final static String MY_DB_intervalltable = "intervall"; final static String MY_DB_alleidtable = "alleidtable"; final static String MY_DB_listenpositiontable = "listenposition"; final static String MY_DB_anzeigekriterientable = "anzeigekriterien"; final static String MY_DB_bl = "bl_table"; int Anzahl_der_Tabs; private static String DB_PATH = "/data/data/com.fk.CheckTasks/databases/"; private static String DB_NAME = "checktaskdb"; private ViewPager viewPager; private TabLayout mTabLayout; private TabAdapter tabAdapter; public String[] data ={"A"}; public int position, ort, dataCount,i,anzahlOrte,chefCount; private String sSQL, tabTitel; private DBHelper myDB; Cursor cTab, cChef; private String[] ortsTitel; private Integer[] chefID; private String[] chefName; private Integer[] ortsID; public TabHost tabHost; private Button button_tabBearbeiten, button_chefBearbeiten; private Integer bl_id=1, tabPos; public CharSequence tabText; @Override protected void onRestart() { super.onRestart(); // Log.d("lifecycle","onRestart invoked"); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.tab_button_layout); Intent intent = getIntent(); tabTitel= intent.getStringExtra("tabname"); chefCount = chefAuslesen(); // zuerst den BL, da die ID für die Tabs benötigt wird ChefTabs_erzeugen(); initViews(); // die Orte/Märkte Tabs tabBar.setTabMode(TabLayout.MODE_SCROLLABLE); button_tabBearbeiten = findViewById(R.id.button_ort); //button_tabBearbeiten.setOnClickListener(this); button_tabBearbeiten.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // Toast.makeText(this, "Einstellungen ", Toast.LENGTH_SHORT).show(); Intent intent = new Intent(getActivity(),TabBearbeitenActivity.class); intent.putExtra("bl",bl_id); startActivity(intent); } }); button_chefBearbeiten = findViewById(R.id.button_bl); //button_tabBearbeiten.setOnClickListener(this); button_chefBearbeiten.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // Toast.makeText(this, "Einstellungen ", Toast.LENGTH_SHORT).show(); Intent intent = new Intent(getActivity(),BL_Activity.class); //intent.putExtra("id",id_orte); startActivity(intent); // finish(); } }); // Tab BL/ Chef die obere erste Tabreihe wird gedrückt tabChef.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { @Override public void onTabSelected(TabLayout.Tab tab) { bl_id= tab.getPosition() +1; tabText = tab.getText(); tabPos = tab.getPosition()+1; initViews(); } @Override public void onTabUnselected(TabLayout.Tab tab) { // zuerst vorhergehenden Tab tabText = tab.getText(); } @Override public void onTabReselected(TabLayout.Tab tab) { int k=0; k++; } }); Intent intent2 = new Intent().setClass(this, TabAdapter.class); intent2.putExtra("chefid", bl_id); }; private Context getActivity() { return this; } @SuppressLint("MissingInflatedId") private View TabViewErstellen(final Context context, final String text) { View view = LayoutInflater.from(context).inflate(R.layout.tab_layout, null); TextView tv = (TextView) view.findViewById(R.id.tabsText); tv.setText(text); return view; } // die Strings[] und Integer[] werden mit den Tabs Bezirksleiter und Markt gefüttert public Integer TabsAuslesen (){ myDB = new DBHelper(this); dataCount=0; ortsID = new Integer [50]; ortsTitel = new String [50]; sSQL = "SELECT * FROM tabtable WHERE bl = "+bl_id+" ;"; cTab = myDB.doSQL(sSQL); if ( cTab != null) { dataCount = cTab.getCount(); i=0; while (cTab.moveToNext() ) { i++; ortsTitel[i] = cTab.getString(1); ortsID[i] = cTab.getInt(0); } } return dataCount; } public Integer getChef() { return bl_id; } public Integer chefAuslesen (){ myDB = new DBHelper(this); chefCount=0; chefID = new Integer[15]; chefName = new String[15]; sSQL = "SELECT * FROM bl_table ;"; cChef = myDB.doSQL(sSQL); if ( cChef != null) { chefCount = cChef.getCount(); i=0; while (cChef.moveToNext() ) { chefName[i] = cChef.getString(1); chefID[i] = cChef.getInt(0); i++; } } bl_id=chefID[0]; return chefCount; } protected void initViews() { int dataCount = 0; myDB = new DBHelper(this); tabBar = findViewById(R.id.tabBar); viewPager2 = findViewById(R.id.view_pager); tabAdapter = new TabAdapter(MainActivity.this,position); //tabAdapter = new TabAdapter.getSupport viewPager2.setAdapter(tabAdapter); //dataCount = chefAuslesen(); // zuerst den BL, da die ID für die Tabs benötigt wird dataCount = TabsAuslesen(); // die Märkte werden in den Tabs hinterlegt new TabLayoutMediator(tabBar, viewPager2, new TabLayoutMediator.TabConfigurationStrategy() { @Override public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) { tabTitel = ortsTitel[position+1]; tab.setText(tabTitel); // ort= tab.getId(); } }).attach(); tabBar.setTabMode(TabLayout.MODE_AUTO); } // die erste, obere Tabreihe wird erzeugt private void ChefTabs_erzeugen() { tabChef = findViewById(R.id.tabChef); for(int i=0;i<=chefCount;){ tabChef.addTab(tabChef.newTab().setText(chefName[i])); i++; } tabChef.setTabMode(TabLayout.MODE_SCROLLABLE); } }
Hier mein FreagmentStateAdapter
Code
Alles anzeigenpackage com.fk.CheckTasks; ...... public class TabAdapter extends FragmentStateAdapter { private int position; public DBHelper myDB; private String sSQL; private int dataCount; Cursor cOrt; int tabCount,bl_id; private ArrayList<Fragment> fragments; public TabAdapter(@NonNull FragmentActivity fm, int position) { super(fm); this.position = position; bl_id = F_checklist.getChef()+1; myDB = new DBHelper(fm.getApplicationContext()); sSQL = "SELECT * FROM tabtable WHERE bl= "+bl_id+" ;"; cOrt = myDB.doSQL(sSQL); dataCount=1; if ( cOrt != null) { dataCount = cOrt.getCount(); } } @NonNull @Override public Fragment createFragment(int position) { Fragment fragment = new F_checklist(); Bundle args = new Bundle(); args.putInt("tabort", position+1); fragment.setArguments(args); return fragment; } @Override public int getItemCount() { return dataCount; } }
-
Habe in der Zwischenzeit die Positionen der einzelnen Tab-Kombinationen in einer Tabelle abgelegt. jetzt funktioniert es, finde es aber nicht so richtig gut ....
aber leider doch nur nach Select, ........
-
Hallo,
wie löse ich das Problem, daß beim Start einer RecyclerView die Position 0 als geklickt angesehen wird. Oder z.B. nach Löschen einer Zeile der Focus wieder auf der Position steht und als Click gewertet wird. Die Funktionen
helfen leider nicht weiter und bringen kein Ergebnis, bzw. die Position wird nicht als geklickt angesehen. Natürlich ist es möglich, daß ich alles falsch anwende.
Danke Wolfgang
-
OK, danke !
-
Habe eine Lösung dank Nono124 Hinweis gefunden, habe mich auf RelativLayout konzentriert und konnte das Layout anpassen.
Es ist klar, dass diese Lösung nicht optimal für alle Geräte ist. Feste Breiten oder Höhen sind halt nicht flexibel für jeden Screen.
XML
Alles anzeigen<?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_marginLeft="2dp" android:layout_marginStart="2dp" android:layout_marginRight="2dp" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" tools:context=".MainActivity"> <com.google.android.material.tabs.TabLayout android:id="@+id/tabChef" android:layout_width="370dp" android:layout_height="30dp" android:background="@drawable/chefbox" /> <Button android:id="@+id/button" android:layout_width="match_parent" android:layout_height="30dp" android:padding="1dp" android:layout_margin="2dp" android:layout_marginStart="1dp" android:layout_toEndOf="@id/tabChef" android:layout_weight="1" android:text="+/-"/> <com.google.android.material.tabs.TabLayout android:layout_below="@id/tabChef" android:id="@+id/tabBar" android:layout_width="370dp" android:layout_height="30dp" android:background="@drawable/box" /> <Button android:id="@+id/button2" android:layout_width="match_parent" android:layout_height="30dp" android:layout_below="@id/button" android:padding="1dp" android:layout_marginStart="1dp" android:layout_toEndOf="@id/tabBar" android:layout_weight="1" android:text="+/-"/> <androidx.viewpager2.widget.ViewPager2 android:id="@+id/view_pager" android:layout_below="@id/tabBar" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout>
-
Hallo,
Leider habe ich noch keine Verschachtelung, auch mit RelativLayout hinbekommen. 2 Tabreihen untereinander müssen sein !
Als Vorlage habe ich eine Variante mit TabHost, die mal ging , ist jetzt aber deprecated.
Kennst Du einen Weg beim Swipen der Tabs den ersten Tab immer stehen zu lassen ?
-
Hallo,
eine weitere Frage.
Ich habe habe zwei horizontale Tablayouts mit ViewPager2 geschaffen. Jetzt möchte ich rechts neben diesen beiden Layouts je einen Button anbringen (fragt bitte nicht warum).
Gibt es dafür eine Lösung ?
Meine entsprechende XML sieht bis jetzt so aus:
XML
Alles anzeigen<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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:layout_marginLeft="2dp" android:layout_marginStart="2dp" android:layout_marginRight="2dp" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <com.google.android.material.tabs.TabLayout android:id="@+id/tabChef" android:layout_width="match_parent" android:layout_height="28dp" android:background="@drawable/chefbox" /> <com.google.android.material.tabs.TabLayout android:id="@+id/tabBar" android:layout_width="match_parent" android:layout_height="33dp" android:background="@drawable/box" /> <androidx.viewpager2.widget.ViewPager2 android:id="@+id/view_pager" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
android-developers.de/core/attachment/1265/
Danke Wolfgang
-
.. es geht doch ...
Ich konnte in der Zwischenzeit doch einen zweiten ViewAdapter realisieren. Mit einem entsprechendem DataModel funktioniert dieser Adapter in einer neuen Acitivity ohne Probleme. Bei den ersten versuchen war das Data_Model nicht exakt aufgebaut (set und get generieren).
-
Hallo,
ich habe jetzt das Problem, daß ich bei meiner Lösung mehrere Views benötige.
Die Haupt-View läuft wunderbar über einen Recycler ViewAdapter und wird aus einem Fragment gestartet.. Für meine 2. View (aus Activity mit snderen Daten) habe ich jetzt versucht einen weiteren ViewAdapter anzulegen, aber es gelingt nicht.
Geht das überhaupt, 2 oder mehr ViewAdapter oder muss man die Views in einem Adapter realisieren ?
Kann jemand helfen ?
-
-
Hallo Gemeinde,
ich bin dabei ein altes Projekt aufzumöbeln. Es sind ca. 25 Dialoge enthalten. In den einzelnen Activitys sind diese auch wunderbar untergebracht, läuft aber so heute nicht mehr.
Problem: "showDialog" wird als deprecated gekennzeichnet.
Code
Alles anzeigen// Aufruf: public void onClickChecklistEintragLoeschen(final View sfNormal) { showDialog(ZeileLoeschenWarnungDialog); // leider jetzt deprecated --- } //der bisherige Dialog: protected Dialog onCreateDialog(int id) { switch (id) { case ZeileLoeschenWarnungDialog: return new AlertDialog.Builder(getParent()) .setMessage(R.string.Txt_Dialog_Loeschen_Warnung) .setCancelable(false) .setPositiveButton(R.string.Button_Loeschen, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { EintragLoeschen(0); // void zum Satz Löschen } }) .setNegativeButton(R.string.Button_Abbrechen, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.cancel(); } }) .create(); case SortierDialog: return new AlertDialog.Builder(getParent()) .setTitle(R.string.Txt_Dialog_Sortieren) .setItems(R.array.Sortierung_Orte, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int item) { dialog.cancel(); SortierFunktion(item); } }) .create(); } return null; }
Wie zu sehen sind hier eigentlich zwei Dialoge in der Activity möglich.
Okay, habe einen Dialog über DialogFragment gebildet. Funktioniert tadellos, auch mit Datenübergabe. Mein DialogFragment sieht so aus:
Code
Alles anzeigen// der Aufruf aus einem Fragmengt buttonLoeschen = view.findViewById(R.id.Button_Loeschen); buttonLoeschen.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // Dialog zum Löschen starten openDialog_Delete(); } }); private void openDialog_Delete(){ DialogFragment newFragment = new MyDialogFragment(); newFragment.show( getActivity().getSupportFragmentManager(), "taskdelete"); } //-------------------------------------------------------------------------------------------------------------------------- // der Dialog im DialogFragment public class MyDialogFragment extends DialogFragment { private MyDialogListener listener; public static final String Tag = "taskdialog"; //widgets private TextView mActionOk, mActionCannel; public String dataGet, dataRecieve, switchDialog; public interface MyDialogListener { void backData(Integer i); } // es wird zurückgegeben, ob gelöscht werden soll, das "sort" ist eigentlich als 2. Dialog geplant @NonNull @Override public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { getParentFragmentManager().setFragmentResultListener("checklistFragment", this, new FragmentResultListener() { @Override public void onFragmentResult(@NonNull String requestKey, @NonNull Bundle result) { dataRecieve = result.getString("loeschen"); //dataRecieve = result.getString("sort"); } }); // if und switch scheint nicht zu gehen, da parralel zwei Aktionen, der Dialog und Resultübergabe, d.h. Text "loeschen" usw. AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setMessage(R.string.Txt_Dialog_Loeschen_Warnung) .setCancelable(false) .setPositiveButton(R.string.Button_Loeschen, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { Bundle result = new Bundle(); // an F_checklist wird delete zurückgegeben ! result.putString("delete", "delete"); getParentFragmentManager().setFragmentResult("dialogFragment", result); } }) .setNegativeButton(R.string.Button_Abbrechen, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.cancel(); } }); return builder.create(); } }
Eine CASE-Schachtelung wie vorher bekomme ich nicht hin. Muss ich jetzt für jedes CASE ein eigenes DialogFragment eröffnen ?
Oder ist es weiterhin sinnvoll, die Dialoge einzeln in der jeweiligen Activity/Fragment situationsbedingt auszuführen ?
Hat jemand einen Hinweis , wie man am besten vorgeht ?
Danke Wolfgang
-
Sorry, das mache ich doch alles, ich habe die Querys nur kürzer gestaltet und richtig, das JOIN entfernt.
Nochmal meine Frage: Kann ich eine Model Klasse aus mehreren Tabellen aufbauen ? Dann würde ich auch wieder JOIN einsetzen. Die vielen ArrayLists würden auch wegfallen. Hatte ja so angefangen, bin aber irgendwie damit nicht klargekommen, weil ich die eine Tabelle abgebildet hatte, aber nicht die View.
-
Es geht nicht um das prinzipielle Verstehen. Man kann das auch einfacher abbilden und schafft somit eine bessere Übersicht und Korrigierbarkeit.
Ich habe auch jahrelang programmiert (hatte aber auch 6 Jahre Pause), die JAVA-Syntax und im Umgang mit Android im Studio ist für mich total neu. Kann ich denn ein Model aus mehren Tabellen zusammenstellen ?
Es ist dann schon klar, daß ich diese mit JOIN verbinde !