Hi,
sorry für das späte Feedback... der Weihnachtsstress.
ABER: Es hat funktioniert!!! Läuft nun alles.
Danke dir für deine Hilfe.
VG
Hi,
sorry für das späte Feedback... der Weihnachtsstress.
ABER: Es hat funktioniert!!! Läuft nun alles.
Danke dir für deine Hilfe.
VG
Wie übergebe ich die Argumente denn im Adapter? Ich bekomme in der MainActivity ja die Datensatz-ID beim Klick auf den Datensatz. Bisher gebe ich sie mittels Intent an die NotenDetailsActivity. Wie kann ich die jetzt an den Adapter übergeben, bzw. dann an die fragments weitergeben?
Hi jogimuc,
erstmal vielen Dank, dass du dir die Zeit nimmst, meinen gesamten Code zu sichten und mir weiterzuhelfen. Ist nicht selbstverständlich.
Danke für die Hinweise, ich werde morgen versuchen, das entsprechend deinen HInweisen umzubauen. Ich halte dich auf dem Laufenden.
Hab dir noch ne PN geschickt.
Hier noch die Layouts:
MainLayout (Liste der Datensätze):
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/notes_toolbar"
android:layout_width="wrap_content"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways">
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/recyclerView"
android:padding="5dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
</androidx.recyclerview.widget.RecyclerView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Alles anzeigen
NotenListActivity (für die Anzeige im RecyclerViev):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/lightYellow"
android:orientation="vertical"
android:weightSum="100"
android:gravity="center_vertical">
<TextView
android:id="@+id/note_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="100"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:paddingLeft="10dp"
android:text="some title"
android:textColor="@color/black"
android:textSize="20sp" />
<TextView
android:id="@+id/note_komponist"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="25"
android:paddingLeft="10dp"
android:text="Dec, 11"
android:textColor="@color/black"
android:textSize="12sp" />
<TextView
android:id="@+id/note_arrangeur"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="25"
android:paddingLeft="10dp"
android:text="Dec, 11"
android:textColor="@color/black"
android:textSize="12sp" />
</LinearLayout>
Alles anzeigen
DetailsLayout mit Tablayout:
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/lightYellow">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/notes_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary">
<include layout="@layout/layout_note_toolbar"/>
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout>
<com.google.android.material.tabs.TabLayout
android:id="@+id/tablayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
app:tabSelectedTextColor="@android:color/white"
app:tabTextColor="@android:color/black">
<com.google.android.material.tabs.TabItem
android:id="@+id/tabPage1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Details 1"/>
<com.google.android.material.tabs.TabItem
android:id="@+id/tabPage2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Details 2" />
<com.google.android.material.tabs.TabItem
android:id="@+id/tabPage3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Details 3" />
<com.google.android.material.tabs.TabItem
android:id="@+id/tabPage4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Details 4" />
</com.google.android.material.tabs.TabLayout>
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</androidx.viewpager.widget.ViewPager>
<FrameLayout
android:id="@+id/DetailsContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</FrameLayout>
</LinearLayout>
Alles anzeigen
fragment_tab1.xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/note_komponist"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/black"
android:textSize="16sp"
android:layout_column="2"/>
</FrameLayout>
Alles anzeigen
fragment_tab2.xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/note_arrangeur"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/black"
android:textSize="16sp"
android:layout_column="2"/>
</FrameLayout>
Alles anzeigen
MainActivity: Liste aller Datensätze; Beim Klick auf einen Datensatz wird die NotenDetailsActivity aufgerufen.
public class MainActivity extends AppCompatActivity implements NotesRecyclerAdapter.OnNoteListener, View.OnClickListener {
private RecyclerView mRecyclerView;
private ArrayList<Note> mNotes = new ArrayList<>();
private NotesRecyclerAdapter mNoteRecyclerAdapter;
private NotenRepository mNotenRepository;
private Button mButtonSync;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView=findViewById(R.id.recyclerView);
mNotenRepository = new NotenRepository(this);
initRecyclerView();
retrieveNotes();
setSupportActionBar((Toolbar)findViewById(R.id.notes_toolbar));
setTitle("My App");
}
private void retrieveNotes() {
mNotenRepository.retrieveNotesTask().observe(this, new Observer<List<Note>>() {
@Override
public void onChanged(@Nullable List<Note> notes) {
if(mNotes.size() > 0) {
mNotes.clear();
}
if(notes != null) {
mNotes.addAll(notes);
}
mNoteRecyclerAdapter.notifyDataSetChanged();
}
});
}
private void initRecyclerView() {
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(linearLayoutManager);
VerticalSpacingItemDecorator itemDecorator = new VerticalSpacingItemDecorator((10));
mRecyclerView.addItemDecoration(itemDecorator);
mNoteRecyclerAdapter=new NotesRecyclerAdapter(mNotes, this);
mRecyclerView.setAdapter(mNoteRecyclerAdapter);
}
@Override
public void onNoteClick(int position) {
Intent intent = new Intent(this, NotenDetailsActivity.class);
intent.putExtra("selected_note", mNotes.get(position));
startActivity(intent);
}
}
Alles anzeigen
NotenDetailsActivity: (enthält das Tablayout mit 4 Tabs).
public class NotenDetailsActivity extends AppCompatActivity implements View.OnClickListener, TabLayout.BaseOnTabSelectedListener {
private Note mInitialNote;
private TextView mViewTitle;
private ViewPager mViewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_noten_details);
mViewPager = findViewById(R.id.viewPager);
TabLayout tabLayout = findViewById(R.id.tablayout);
tabLayout.setupWithViewPager(mViewPager);
PageAdapter pageAdapter = new PageAdapter(getSupportFragmentManager(), tabLayout.getTabCount());
mViewPager.setAdapter(pageAdapter);
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(this);
mInitialNote = getIntent().getParcelableExtra("selected_note");
mViewTitle = findViewById(R.id.note_toolbar_title);
mViewTitle.setText(mInitialNote.getTitle());
Bundle bundle = new Bundle();
bundle.putString("komponist", mInitialNote.getKomponist());
Tab1Fragment fragment = new Tab1Fragment();
fragment.setArguments(bundle);
getSupportFragmentManager().beginTransaction().replace(R.id.DetailsContainer, fragment).commit();
}
@Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
@Override
public void onClick(View view) {
finish();
}
@Override
public void onBackPressed() {
super.onBackPressed();
}
}
Alles anzeigen
Tab1Fragment: (Tab2-4 sind genauso aufgebaut, enthalten nur unterschiedliche Datenfelder)
public class Tab1Fragment extends Fragment {
public Tab1Fragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_tab1, container, false);
TextView mViewKomponist = view.findViewById(R.id.note_komponist);
if (getArguments() != null) {
String tKomponist = getArguments().getString("komponist");
mViewKomponist.setText(tKomponist);
return view;
}
else
{
return nothing;
}
}
}
Alles anzeigen
Tab2Fragment:
public class Tab2Fragment extends Fragment {
public Tab2Fragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_tab2, container, false);
TextView mViewArrangeur = view.findViewById(R.id.note_arrangeur);
if (getArguments() != null) {
String tArrangeur = getArguments().getString("arrangeur");
mViewArrangeur.setText(tArrangeur);
return view;
}
else
{
return nothing;
}
}
}
Alles anzeigen
Hi,
hier der gesamte Code:
NotenDatabase:
@Database(entities = {Note.class}, version = 1)
public abstract class NotenDatabase extends RoomDatabase {
public static final String DATABASE_NAME = "MyDatabase.db";
private static NotenDatabase instance;
static NotenDatabase getInstance(final Context context) {
if (instance == null) {
//instance = Room.databaseBuilder(context.getApplicationContext(), NotenDatabase.class, DATABASE_NAME).build();
instance = Room.databaseBuilder(context.getApplicationContext(), NotenDatabase.class,DATABASE_NAME).
createFromAsset("databases/MyDatabase.db").build();
}
return instance;
}
public abstract NoteDao getNoteDao();
}
Alles anzeigen
NotenDao:
@Dao
public interface NoteDao {
@Insert
long[] insertNotes(Note... notes);
@Query("SELECT * FROM Noten ORDER BY Titel ASC")
LiveData<List<Note>> getNotes();
@Delete
int delete(Note... notes);
@Update
int updateNotes(Note... notes);
}
Alles anzeigen
NotenRepository:
public class NotenRepository {
private NotenDatabase mNotenDatabase;
public NotenRepository(Context context) {
mNotenDatabase = NotenDatabase.getInstance(context);
}
public LiveData<List<Note>> retrieveNotesTask() {
return mNotenDatabase.getNoteDao().getNotes();
}
}
Alles anzeigen
NotesRecyclerAdapter:
public class NotesRecyclerAdapter extends RecyclerView.Adapter<NotesRecyclerAdapter.ViewHolder> {
private ArrayList<Note> mNotes = new ArrayList<>();
private OnNoteListener mOnNoteListener;
public NotesRecyclerAdapter(ArrayList<Note> notes, OnNoteListener onNoteListener) {
this.mNotes = notes;
this.mOnNoteListener = onNoteListener;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.noten_list_activity, viewGroup, false);
return new ViewHolder(view, mOnNoteListener);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) {
viewHolder.title.setText(mNotes.get(i).getTitle());
String tKomponist = "";
String tArrangeur = "";
if (!mNotes.get(i).getKomponist().isEmpty()) {
tKomponist = "Komp: " + mNotes.get(i).getKomponist();
}
if (!mNotes.get(i).getArrangeur().isEmpty()) {
tArrangeur = "Arr: " + mNotes.get(i).getArrangeur();
}
viewHolder.komponist.setText(tKomponist);
viewHolder.arrangeur.setText(tArrangeur);
}
@Override
public int getItemCount() {
try {
return mNotes.size();
} catch (Exception e) {
return 0;}
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
TextView title, komponist, arrangeur;
OnNoteListener onNoteListener;
public ViewHolder(@NonNull View itemView, OnNoteListener onNoteListener) {
super(itemView);
title = itemView.findViewById(R.id.note_title);
komponist = itemView.findViewById(R.id.note_komponist);
arrangeur = itemView.findViewById(R.id.note_arrangeur);
this.onNoteListener = onNoteListener;
itemView.setOnClickListener(this);
}
@Override
public void onClick(View view) {
onNoteListener.onNoteClick(getAdapterPosition());
}
}
public interface OnNoteListener{
void onNoteClick(int position);
}
}
Alles anzeigen
PageAdapter:
public class PageAdapter extends FragmentStatePagerAdapter {
private int numOfTabs;
public PageAdapter(FragmentManager fm, int numOfTabs) {
super(fm);
this.numOfTabs = numOfTabs;
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
Tab1Fragment tab1fragment = new Tab1Fragment();
return tab1fragment;
case 1:
Tab2Fragment tab2fragment = new Tab2Fragment();
return tab2fragment;
case 2:
Tab3Fragment tab3fragment = new Tab3Fragment();
return tab3fragment;
case 3:
Tab4Fragment tab4fragment = new Tab4Fragment();
return tab4fragment;
default:
return null;
}
}
@Override
public int getCount() {
return numOfTabs;
}
}
Alles anzeigen
Class Note:
@Entity(tableName = "Noten")
public class Note implements Parcelable {
@PrimaryKey(autoGenerate=true)
@ColumnInfo(name="ID")
private int id;
@ColumnInfo(name="Titel")
String title;
@ColumnInfo(name="Komponist")
String komponist;
@ColumnInfo(name="Arrangeur")
String arrangeur;
protected Note(Parcel in) {
id = in.readInt();
title = in.readString();
komponist = in.readString();
arrangeur = in.readString();
}
public static final Creator<Note> CREATOR = new Creator<Note>() {
@Override
public Note createFromParcel(Parcel in) {
return new Note(in);
}
@Override
public Note[] newArray(int size) {
return new Note[size];
}
};
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getKomponist() {
return komponist;
}
public void setKomponist(String komponist) {
this.komponist = komponist;
}
public String getArrangeur() {
return arrangeur;
}
public void setArrangeur(String arrangeur) {
this.arrangeur = arrangeur;
}
public static Creator<Note> getCREATOR() {
return CREATOR;
}
@Ignore
public Note() {
}
@Override
public String toString() {
return "Note{" +
"id=" + id +
", title='" + title + '\'' +
", komponist='" + komponist + '\'' +
", arrangeur='" + arrangeur + '\'' +
'}';
}
public Note(int id, String title, String komponist, String arrangeur) {
this.id = id;
this.title = title;
this.komponist = komponist;
this.arrangeur = arrangeur;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeInt(id);
parcel.writeString(title);
parcel.writeString(komponist);
parcel.writeString(arrangeur);
}
}
Alles anzeigen
Hi,
danke für diene Antwort. Natürlich habe ich täglich reingeschaut, das Problem besteht ja immer noch. Anscheinend war ich nur nicht angemeldet.
Bevor ich nun versuche, meinen Code irgendwie halbvernünftig zu bearbeiten: Wie müsste das ganze denn vernünftig aussehen?
Ziel soll es eben sein, eine Liste (mit Datensätzen aus einer Datenbank) anzuzeigen, beim Klick darauf sollen die Detaildaten zum DS angezeigt werden (auf 3 Tabs verteilt).
Ein Swipen zwischen den Tabs wäre dann schon gut.
Ich muss dazu sagen, dass ich völliger Java-Neuling bin (bisher nur VB / C#).
Ich habe im Netz verschiedene Tuts gefunden, allerdings nur entweder "Liste mit Klick auf Detailanzeige (sep. Avtivity), oder die allgemeine Verwendung von Tabs. Ich bekomm es aber nicht hin, beides zu verknüpfen.
Danke & Grüße
Hi zusammen,
ich habe eine MainActivity mit einem RecyclerView, welcher Daten aus einer SQLite-Datenbank anzeigt. Beim Klick auf einen Datensatz soll sich eine DetailActivity öffnen, und weitere Details zu dem jeweiligen Datensatz anzeigen.
Ich habe auf der DetailActivity ein TabLayout, da die Detaildaten auf 3 Tabs angezeigt werden sollen. Für jeden Tab existiert ein Fragment.
Wenn ich nun aber einen Datensatz in der MainActivity anklicke, öffnet sich zwar das fragment, aber ohne Daten. Im Logfile sieht man, dass der OnCreateView des fragments insgesamt 3x aufgerufen wird. Beim ersten mal ohne Werte, beim 2. Mal werden die Werte übergeben, beim 3. Mal dann wieder leer.
Kann mir jemand sagen, warum das fragment 3x aufgerufen wird, und wie ich das beheben kann?
Danke euch!
Meine MainActivity:
}
mNoteRecyclerAdapter.notifyDataSetChanged();
}
});
}
private void initRecyclerView() {
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(linearLayoutManager);
VerticalSpacingItemDecorator itemDecorator = new VerticalSpacingItemDecorator((10));
mRecyclerView.addItemDecoration(itemDecorator);
mNoteRecyclerAdapter=new NotesRecyclerAdapter(mNotes, this);
mRecyclerView.setAdapter(mNoteRecyclerAdapter);
}
@Override
public void onNoteClick(int position) {
Intent intent = new Intent(this, NotenDetailsActivity.class);
intent.putExtra("selected_note", mNotes.get(position));
startActivity(intent);
}
}
Alles anzeigen
NotenDetailsActivity:
public class NotenDetailsActivity extends AppCompatActivity implements View.OnClickListener{
// ui components
private TextView mViewTitle;
private TextView mViewKomponist;
private TextView mViewArrangeur;
private TextView mViewVerlag;
private RelativeLayout mBackArrowContainer;
private ImageButton mBackArrow;
// vars
private Note mInitialNote;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_noten_details);
mViewTitle = findViewById(R.id.note_toolbar_title);
TabLayout tabLayout = findViewById(R.id.tablayout);
TabItem tabChats = findViewById(R.id.tabPage1);
TabItem tabStatus = findViewById(R.id.tabPage2);
TabItem tabCalls = findViewById(R.id.tabPage3);
ViewPager viewPager = findViewById(R.id.viewPager);
PageAdapter pageAdapter = new PageAdapter(getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(pageAdapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
mBackArrow = findViewById(R.id.toolbar_back_arrow);
mBackArrowContainer = findViewById(R.id.back_arrow_container);
setListeners();
if(getIntent().hasExtra("selected_note")) {
setNoteProperties();
}
}
private void setListeners() {
mBackArrow.setOnClickListener(this);
}
public void setNoteProperties() {
mInitialNote = getIntent().getParcelableExtra("selected_note");
mViewTitle.setText(mInitialNote.getTitle());
Bundle bundle = new Bundle();
bundle.putString("komponist", mInitialNote.getKomponist());
Tab1Fragment fragment = new Tab1Fragment();
fragment.setArguments(bundle);
getSupportFragmentManager().beginTransaction().replace(R.id.fragment1, fragment).commit();
}
@Override
public void onClick(View view) {
finish();
}
@Override
public void onBackPressed() {
super.onBackPressed();
}
}
Alles anzeigen
Tab1Fragment:
public class Tab1Fragment extends Fragment {
public Tab1Fragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_tab1, container, false);//Inflate Layout
Log.d("", "onCreateView: TRIGGERED");
TextView mViewKomponist = view.findViewById(R.id.note_komponist);
if (getArguments() != null) {
String tKomponist = getArguments().getString("komponist");
Log.d("", "onCreateView: " + tKomponist);
mViewKomponist.setText(tKomponist);
}
else
{
Log.d("", "onCreateView: NOTHING");
}
return view;
}
}
Alles anzeigen
Und das Logfile, in dem man erkennt, dass das fragment 3x aufgerufen wird:
D/EGL_emulation: eglMakeCurrent: 0xae834ca0: ver 2 0 (tinfo 0xae8393f0)
D/OpenGLRenderer: Enabling debug mode 0
D/EGL_emulation: eglMakeCurrent: 0xae834ca0: ver 2 0 (tinfo 0xae8393f0)
D/: onCreateView: TRIGGERED
onCreateView: NOTHING
D/: onCreateView: TRIGGERED
onCreateView: Grünbauer, Wolfgang
D/: onCreateView: TRIGGERED
onCreateView: NOTHING
D/EGL_emulation: eglMakeCurrent: 0xae834ca0: ver 2 0 (tinfo 0xae8393f0)
I/Choreographer: Skipped 32 frames! The application may be doing too much work on its main thread.
Alles anzeigen