Before using FragmentStateAdapter. I was using FragmentPagerAdapter then everything was fine but when I migrated from FragmentPagerAdapter to FragmentStateAdapter to reduce memory usage. The issue that I'm facing is that when RecyclerView is at the top position then clicking on any item in the list is not working. If I scroll the RecyclerView a bit down then onClick works fine. This problem was not happening with SwipeRefreshLayout. When I remove SwipeRefreshLayout from parent of RecyclerView. It working fine. How can I use it with SwipeRefreshLayout?
I'm using children Fragments inside a parent Fragment like this
This is the code of Parent Fragment.
public class DailyFragment extends Fragment {
private FragmentDailyBinding binding;
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
binding = FragmentDailyBinding.inflate(inflater, container, false);
MyChildFragmentAdapter childFragmentAdapter = new MyChildFragmentAdapter(this.getChildFragmentManager(), this.getLifecycle()); // I'm showing these fragment in Parent fragment. So that I'm using getChildFragmentManager()
childFragmentAdapter.addFragment(new FirstFragment(),"first");
childFragmentAdapter.addFragment(new SecondFragment(),"second");
childFragmentAdapter.addFragment(new ThirdFragment(),"third");
childFragmentAdapter.addFragment(new FourthFragment(),"fourth");
childFragmentAdapter.addFragment(new FifthFragment(),"fifth");
binding.dailyViewPager.setAdapter(childFragmentAdapter);
new TabLayoutMediator(binding.dailyTabLayout, binding.dailyViewPager, (tab, position) -> tab.setText(childFragmentAdapter.fragmentsArrayListTitle.get(position))).attach();
binding.dailyViewPager.setOrientation(ViewPager2.ORIENTATION_VERTICAL);
return binding.getRoot();
}
// FragmentStateAdapter
public static class MyChildFragmentAdapter extends FragmentStateAdapter {
private final ArrayList<Fragment> fragmentsArrayList = new ArrayList<>();
private final ArrayList<String> fragmentsArrayListTitle = new ArrayList<>();
public MyChildFragmentAdapter(#NonNull FragmentManager fragmentManager, #NonNull Lifecycle lifecycle) {
super(fragmentManager, lifecycle);
}
public void addFragment(Fragment fragment, String title) {
fragmentsArrayList.add(fragment);
fragmentsArrayListTitle.add(title);
}
#NonNull
#Override
public Fragment createFragment(int position) {
return fragmentsArrayList.get(position);
}
#Override
public int getItemCount() {
return fragmentsArrayList.size();
}
}
}
and This this XML of FirstFragment()
<?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_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent"
tools:context=".ChieldFragment.dailyChield.MahadevFragment">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="#+id/mahadevSwipe"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/mahadevRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</LinearLayout>
My question is similar to this question
ViewPager2 conflicting with SwipeRefreshLayout
I checked these answers but not solved my problem.
I had same problem not so long ago. I fixed mine by adding NestedScrollView as SwipeRefreshLayout child, and then simply put your recycler layout as NestedScrollView's child. See example below :
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="#+id/mahadevSwipe"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
// I didn't put mandatory constraints, but you'll have to
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/mahadevRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.core.widget.NestedScrollView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
Alternatively, you could also keep your code like it is, and add custom scrolling behavior with scroll listener.
Tell me if my first guess don't work, i'll give you example of custom scroll handling.
Try adding app:layout_behavior="#string/appbar_scrolling_view_behavior" to all views under coordinator layout.
Related
Good day - I'm new to recyclerViews and connecting to Room database. I've got one working with the help from a tutorial and now I want to add to it. My aim is to:
Implement a Room database which in turn presents data to the user via a recyclerView.
Have 1 recyclerView in the main activity and a 2nd recyclerView in a second activity. I'm trying to have a different layout in each activity as shown in the following links.
Main activity:
Second activity:
The issue I'm having is even though the XML files are unique for each activity, along with the variables within, the name of the recyclerView, and also the methods for each activity, the layout in the second activity shows in the first activity.
activity_main has the following:
<androidx.recyclerview.widget.RecyclerView
android:layout_marginTop="100dp"
android:id="#+id/recycler_view111"
android:layout_width="match_parent"
android:layout_height="114dp"
tools:listitem="#layout/testing" />
The second activity XML file has the following:
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="488dp"
tools:listitem="#layout/testing1_item" />
Can someone please help me identify why the same recyclerView is shown across the 2 activities please?
To trouble-shoot, I've:
Gone through all the XML files to ensure there is no issue with the names of the files/methods etc.
Copied the layout from the activity_main xml and applied it to the second xml file. This then in turn displayed the layout that I'm testing within in MainActivity across both activities.
MainActivity uses the activity_main.xml which uses a test file called testing.xml - code as follows:
MainActivity:
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
Intent intent = new Intent(getApplicationContext(), AllWordsActivity.class);
startActivity(intent);
}
});
RecyclerView recyclerView111 = findViewById(R.id.recycler_view111);
recyclerView111.setLayoutManager(new LinearLayoutManager(this));
recyclerView111.setHasFixedSize(true);
NoteAdapter adapter = new NoteAdapter();
recyclerView111.setAdapter(adapter);
noteViewModel.getAllNotes().observe(this, new Observer<List<Note>>()
{
#Override
public void onChanged(List<Note> notes)
{
adapter.setNotes(notes);
}
});
activity_main.xml
<?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">
<Button
android:id="#+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
android:layout_marginTop="500dp"
android:layout_marginRight="50dp"
android:background="#color/cardview_shadow_start_color"
android:maxLines="1"
android:text="Open new Activity!"
android:textColor="#color/black"
android:textSize="20dp"
android:textStyle="bold" />
<androidx.recyclerview.widget.RecyclerView
android:layout_marginTop="100dp"
android:id="#+id/recycler_view111"
android:layout_width="match_parent"
android:layout_height="114dp"
tools:listitem="#layout/testing" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
testing.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp">
<TextView
android:id="#+id/text_view_priority1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:textColorHighlight="#color/black"
android:text="1"
android:textAppearance="#style/TextAppearance.AppCompat.Large" />
<TextView
android:id="#+id/text_view_title1"
android:layout_width="323dp"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_marginStart="183dp"
android:layout_toStartOf="#id/text_view_priority1"
android:ellipsize="end"
android:maxLines="1"
android:text="Title1"
android:textAppearance="#style/TextAppearance.AppCompat.Large" />
<TextView
android:id="#+id/text_view_description1"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_alignParentEnd="true"
android:layout_below="#id/text_view_title1"
android:text="Description1" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
The second activity is based on a class called AllWordsActivity" which uses activity_all_words which uses note_item test - code as follows:
AllWordsActivity.java
private NoteViewModel noteViewModel;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_all_words);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setHasFixedSize(true);
NoteAdapter adapter = new NoteAdapter();
recyclerView.setAdapter(adapter);
//noteViewModel = ViewModelProviders.of(this).get(NoteViewModel.class);
noteViewModel.getAllNotes().observe(this, new Observer<List<Note>>()
{
#Override
public void onChanged(List<Note> notes)
{
adapter.setNotes(notes);
}
});
activity_all_words.xml
<?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=".AllWordsActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="488dp"
tools:listitem="#layout/note_item" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
note_item.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp">
<TextView
android:id="#+id/text_view_priority"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_alignParentEnd="true"
android:textColor="#color/purple_500"
android:text="1"
android:textAppearance="#style/TextAppearance.AppCompat.Large"/>
<TextView
android:id="#+id/text_view_title"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="Title"
android:textAppearance="#style/TextAppearance.AppCompat.Large"
android:maxLines="1"
android:layout_toStartOf="#id/text_view_priority"
android:layout_alignParentStart="true"
android:ellipsize="end"/>
<TextView
android:id="#+id/text_view_description"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_below="#id/text_view_title"
android:text="Description" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
Code for noteAdapter:
```public class NoteAdapter extends RecyclerView.Adapter<NoteAdapter.NoteHolder>
{
private List notes = new ArrayList<>();
#NonNull
#Override
public NoteHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType)
{
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.note_item, parent, false);
return new NoteHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull NoteHolder holder, int position)
{
Note currentNote = notes.get(position);
holder.textViewTitle.setText(currentNote.getTitle());
holder.textViewDescription.setText(currentNote.getDescription());
holder.textViewPriority.setText(String.valueOf(currentNote.getPriority()));
}
#Override
public int getItemCount()
{
return notes.size();
}
public void setNotes(List<Note> notes)
{
this.notes = notes;
notifyDataSetChanged();
}```
The problem is that both activities use the same adapter for their list view: NoteAdapter adapter = new NoteAdapter();. In turn, NoteAdapter only inflates note_item.xml for each item in the list:
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.note_item, parent, false);
To fix this, you need to either change NoteAdapter to work with multiple layout files for its rows. Or you need to create a different adapter for each RecyclerView.
Original Answer:
It sounds like you are seeing the same items displaying in both of your recycler views. The problem is that both the MainActivity and the AllWordsActivity have these lines:
NoteAdapter adapter = new NoteAdapter();
recyclerView.setAdapter(adapter);
noteViewModel.getAllNotes().observe(this, new Observer<List<Note>>()
{
#Override
public void onChanged(List<Note> notes)
{
adapter.setNotes(notes);
}
});
So both activities are getting data from the same ViewModel to display. To display different data, use a different ViewModel in the MainActivity.
p.s. I suggest using consistent naming. You have AllWordsActivity and NotesAdapater. Either use AllWords or Notes, but don't mix and match.
I want to start an activity when i click on one of the item of my RecyclerView. Unfortunately when i click on an item nothing happens and I'm stuck here.
I think the code into the onClick method is right (But maybe I'm wrong). I tried to add a Log.d to see if the listener works but i can't see it in the logcat when i click on an item. I'm new on programming so it can be a stupid error. Thanks for help :)
public class UsersRecyclerAdapter extends RecyclerView.Adapter<UsersRecyclerAdapter.ViewHolder> {
private Context context;
private List<Users> usersList;
public UsersRecyclerAdapter(Context context, List<Users> usersList) {
this.context = context;
this.usersList = usersList;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.users_row, parent, false);
return new ViewHolder(view, context);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
final Users users = usersList.get(position);
holder.firstName.setText(users.getFirstName());
holder.lastName.setText(users.getLastName());
holder.classe.setText(users.getClasse());
String avatarURL = users.getAvatar();
Picasso.get().load(avatarURL).into(holder.avatar);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.i("MyApp","I am here");
context = view.getContext();
Intent intent = new Intent(context, PDFPostListActivity.class);
// String userID = users.getUserID();
// intent.putExtra("userID", userID);
context.startActivity(intent);
}
});
}
EDIT. Here is the root view (users_row):
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
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="wrap_content"
android:layout_margin="5dp">
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="#+id/imageViewAVATAR"
android:layout_width="50dp"
android:layout_height="50dp"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:paddingTop="10dp" />
<TextView
android:id="#+id/textViewfistName"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginEnd="10dp"
android:gravity="center"
android:textSize="21sp"
android:textStyle="italic" />
<TextView
android:id="#+id/textViewlastName"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginEnd="10dp"
android:gravity="center"
android:textSize="21sp"
android:textStyle="italic" />
<TextView
android:id="#+id/textViewclass"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:textSize="21sp"
android:textStyle="italic" />
</LinearLayout>
</HorizontalScrollView>
</androidx.cardview.widget.CardView>
What's the root view of the view holder? Set it to be clickable since you set onClickListener on itemView of view holder.
Great thanks to #Mike M. who rapidly answer in the comment below the question. I paste the message:
When you call setOnClickListener() on itemView, it's setting that on the , since that's the outermost View there. The nested within it is preventing it from receiving click events. Assuming that's all that going to be in that layout, then the simplest fix would probably be to simply set the OnClickListener on the instead. You'll need to give it an android:id, find it with findViewById() just like you did the TextViews, and then call setOnClickListener() on that, instead of itemView.
I've created an acitvity that must have two pages. Those two pages shouldn't work like two different and unrelated activities, but like, let's say, one activity with two work area. Switching between them just with sliding right or left.
So I've impleneted it and switching works, but I can't get access to the object inside ViewPager.
Description:
Parent activity activity_setdetail.xml has two area: list view_setdetail_1.xml - of items and view_setdetail_2.xml - some settings. So, those two areas relate to different *.xml.
XMLs
activity_setdetail.xml
<android.support.v4.view.ViewPager
android:id="#+id/vpager"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="2dp"
android:layout_marginEnd="2dp"
android:layout_marginLeft="2dp"
android:layout_marginRight="2dp"
android:layout_marginStart="2dp"
android:layout_marginTop="2dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
view_setdetail_1.xml it goes to ViewPager vpager as right side area
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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">
<ListView
android:id="#+id/listViewOfWords"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="2dp"
android:layout_marginLeft="2dp"
android:layout_marginRight="2dp"
android:layout_marginStart="2dp"
android:layout_marginTop="8dp"
android:clickable="true"
android:focusable="true"
android:paddingBottom="20dp"
android:textAlignment="center"
app:layout_constraintBottom_toTopOf="#+id/txtToLBL"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/txtToLBL"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:text="#string/view_goToSettings"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
</android.support.constraint.ConstraintLayout>
view_setdetail_2.xml it goes to ViewPager vpager as left side area
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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">
<TextView
android:id="#+id/txtCardsQTYinLessonlbl"
android:layout_width="0dp"
android:layout_height="38dp"
android:layout_marginLeft="2dp"
android:layout_marginStart="2dp"
android:layout_marginTop="2dp"
android:gravity="center_vertical"
android:text="#string/txtCardsQTYinLessonLBLString"
android:textAlignment="center"
android:textColor="?attr/editTextColor"
android:textSize="16sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="#+id/etxtCardsQTYinLesson"
android:layout_width="34dp"
android:layout_height="wrap_content"
android:layout_marginEnd="2dp"
android:layout_marginLeft="2dp"
android:layout_marginRight="2dp"
android:layout_marginStart="2dp"
android:layout_marginTop="2dp"
android:ems="10"
android:imeOptions="actionDone"
android:inputType="number"
android:text="99"
android:textAlignment="center"
android:textSize="14sp"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toRightOf="#+id/txtCardsQTYinLessonlbl"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/txtTolistLBL"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:text="#string/view_goToList"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
</android.support.constraint.ConstraintLayout>
Resource file that enumerate screens for activity_setdetail.xml
public enum ResourcesModel {
FIRST_SCREEN(R.string.view_setdetail_1, R.layout.view_setdetail_1), SECOND_SCREEN(R.string.view_setdetail_2, R.layout.view_setdetail_2);
private int mTitleResourceId;
private int mLayoutResourceId;
ResourcesModel(int titleResId, int layoutResId) {
mTitleResourceId = titleResId;
mLayoutResourceId = layoutResId;
}
public int getTitleResourceId() {
return mTitleResourceId;
}
public int getLayoutResourceId() {
return mLayoutResourceId;
}
}
Adapter:
import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import am.slotvin.hoodiesoft.by.enums.ResourcesModel;
public class SimplePagerAdapter extends PagerAdapter {
private Context mContext;
public SimplePagerAdapter(Context context) {
mContext = context;
}
#Override
public Object instantiateItem(ViewGroup viewGroup, int position) {
ResourcesModel resources = ResourcesModel.values()[position];
LayoutInflater inflater = LayoutInflater.from(mContext);
ViewGroup layout = (ViewGroup) inflater.inflate(
resources.getLayoutResourceId(), viewGroup, false);
viewGroup.addView(layout);
return layout;
}
#Override
public void destroyItem(ViewGroup viewGroup, int position, Object view) {
viewGroup.removeView((View) view);
}
#Override
public int getCount() {
return ResourcesModel.values().length;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
#Override
public CharSequence getPageTitle(int position) {
ResourcesModel customPagerEnum = ResourcesModel.values()[position];
System.out.println("SimplePagerAdapter CharSequence getPageTitle" + position);
return mContext.getString(customPagerEnum.getTitleResourceId());
}
}
Java class for activity_setdetail.xml. I've reduced code just to only textview. But in reality I have ListView there and other stuff. Nevertheless, I can't influence even to textview.
public class SetDetail extends AppCompatActivity {
private String setName;
private int setID;
TextView txtToLBL;
SimplePagerAdapter spa;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setName = getIntent().getStringExtra("setName");
setID = getIntent().getIntExtra("setID", 0);
setTitle(this.getString(R.string.activity_setdetailLabel) + setName);
setContentView(R.layout.activity_setdetail);
spa = new SimplePagerAdapter(this);
ViewPager viewPager = (ViewPager) findViewById(R.id.vpager);
if (viewPager != null) {
viewPager.setAdapter(spa);
}
txtToLBL = (TextView) findViewById(R.id.txtToLBL); //doesn't work
//txtToLBL.setText("bla-bla-bla"); //error - android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
LayoutInflater inflater = LayoutInflater.from(this);
View v = inflater.inflate(R.layout.view_setdetail_1, null, false);
txtToLBL = (TextView) v.findViewById(R.id.txtToLBL);
txtToLBL.setText("bla-bla-bla");//also doesn't work. No errors, just no changes.
}
}
So the question is - How to gegt access to elements on views that loaded in a ViewPager?
I found similar questions, but they didn't work for me.
UPDATE 1:
So, I've completely moved all code (also a bunch of listeners) to my SimplePagerAdapter. Now it should be renamed, because it is not universal anylonger and closely-coupled with the java class of parent activity. Looks not very good, but the only way I found at the moment. Though works OK, without freezing. Still be good to hear more elegant solution.
A ViewPager inflates 3 fragments at a time, the current fragment in view and a fragment on both left and right side of it. Since, your ViewPager has only two fragments both are inflated. So you can use something like viewPager.findViewById(resId) where resId is the Id of the view you want to access
I have the same kind of issue, the viewPager and the PagerAdapter should have been designed with a callback for when it's finished loading it's views. If I put code I want to run inside onPageSelected it all works, its just not available onCreate or onResume (presumably because the view is not instantiated by the pager yet.. If I had hair I'd be pulling it out trying to set default text on TextViews when my activity is Created...
I am doing a time management app for android for my project in school. So there is a class called Activity which represents the activities done by the user through the day(Like going to school,listening to music,eating etc). Activity objects have an instant variable called done which is type of boolean and another insant variable Tags which is a Tag array. There is need for boolean done because user can enter activities for the future and later he/she can mark it as done. Tag class is for the user to label their activities(For example an activity can have tags: sport and hobby at the same time).These activities entered by the user to the program are shown in a fragment called Activities fragment. There will be 2 different Listviews in this fragment one for done and the other for undone activities. So I wrote my xml code so that it would have 2 Listviews on top of each other and added this listviews to my fragment. However, when I run my code I only can see one of the Listviews, the other one does not show up.This is how my xml file look like:(here is the picture of the design:http://postimg.org/image/a7u1ynfzb/)
<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="match_parent"
android:orientation="vertical"
tools:context="com.beter.timehole.fragment.ActivitiesFragment">
<!-- TODO: Update blank fragment layout -->
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="#+id/listView1"
/>
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="#+id/listView2"
/>
</LinearLayout>
Here is my code for fragment class:
public class ActivitiesFragment extends Fragment {
public ActivitiesFragment() {
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ArrayList<Tag> tags1= new ArrayList<Tag>();
tags1.add(new Tag("Tag1"));
ArrayList<Tag> tags2= new ArrayList<Tag>();
tags2.add(new Tag("Tag2"));
com.beter.timehole.core.Activity doneSample = new com.beter.timehole.core.Activity("Work",true,70,"16 50","17 00",tags1,"did it");
com.beter.timehole.core.Activity undoneSample = new com.beter.timehole.core.Activity("Fun",false,30,"13 30","14 00",tags2,"will do it");
View rootView = inflater.inflate(R.layout.activity_fragment, container, false);
ArrayList<com.beter.timehole.core.Activity> doneActivities = new ArrayList<com.beter.timehole.core.Activity>();
doneActivities.add(doneSample);
ListView doneList = (ListView) rootView.findViewById(R.id.listView1);
doneList.setAdapter(new ArrayAdapter<com.beter.timehole.core.Activity>(getActivity(), R.layout.support_simple_spinner_dropdown_item, doneActivities));
ArrayList<com.beter.timehole.core.Activity> undoneActivities = new ArrayList<com.beter.timehole.core.Activity>();
undoneActivities.add(undoneSample);
ListView undoneList = (ListView) rootView.findViewById(R.id.listView2);
undoneList.setAdapter(new ArrayAdapter<com.beter.timehole.core.Activity>(getActivity(),R.layout.support_simple_spinner_dropdown_item,undoneActivities));
return rootView;
}
}
Try to Change layout_height="0dp" .
Try this layout code.
`
<!-- TODO: Update blank fragment layout -->
<ListView
android:id="#+id/listView1"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1" />
<ListView
android:id="#+id/listView2"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1" />
`
If this is not working try to check your code or put your complete code here.
Please try this
<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="match_parent"
android:orientation="vertical"
tools:context="com.beter.timehole.fragment.ActivitiesFragment">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:id="#+id/listView1"
/>
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:id="#+id/listView2"
/></LinearLayout>
so I know there are a few topics around here that ask about this but none seemed to be the cause of my issue. I have an ActionBarActivity that is going to be switching between a few different fragments, but I'm having a problem getting one of the fragments to show up. The activity does show a fragment when it is first loaded and does that fine. Here is the code that is setting up the initial fragment with the method to switch between fragments that I'm using.
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_container);
final ActionBar actionBar = getSupportActionBar();
actionBar.setTitle("");
if (savedInstanceState == null) navigateTo(START_SCREEN);
}
public void navigateTo(int sectionNumber, Serializable objectParam) {
Fragment fragment = null;
switch (sectionNumber) {
case START_SCREEN:
fragment = createStartScreenFragment(); //returns an instance of the class for this fragment
break;
case SCREEN_TWO:
fragment = createSecondScreenFragment(); //returns an instance of the class for this fragment
break;
}
if (fragment == null) return;
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction trans = fm.beginTransaction();
trans.add(R.id.activity_container, fragment, fragment.getTag());
trans.commit();
trans.show(fragment);
}
activity_containers.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:id="#+id/activity_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
The first fragment that loads successfuly
<GridLayout
android:id="#+id/fragment_start_screen"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.android.Activity">
<TextView
android:id="#+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
/>
...
</GridLayout>
And here is the fragment xml that isn't showing up
<TextView android:id="#+id/section_label" android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ListView
android:id="#+id/list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scrollbars="vertical"
android:fadingEdge="vertical"
android:cacheColorHint="#00000000"
android:fastScrollEnabled="true"
android:padding="2dp">
</ListView>
And here is the misbehaving fragments relevant code:
public class SecondFragment extends Fragment {
public final static int SECTION_NUMBER = 1;
private String mTag = "TAG";
private ParentActivity parentActivity;
public SecondFragment() {
}
public static fragment newInstance() {
SecondFragment fragment = new SecondFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
#Override
public void onAttach(final Activity activity) {
super.onAttach(activity);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
parentActivity = (ParentActivity) getActivity();
View rootView = inflater.inflate(R.layout.fragment_second_fragment, container, false);
ListView list = (ListView) rootView.findViewById(R.id.list);
return super.onCreateView(inflater, container, savedInstanceState);
}
}
The biggest problem I'm having here is that there is no error message shown. The text view in the first fragment is supposed to trigger the second fragment to show up on the screen. This used to work when I had that fragment as a DialogFragment and just called .show() on an instance of it. I need it to be a regular fragment now and it doesn't show up. There's no error message that I can see, though debugging it does show it running through all of my code successfully and it looks like its properly inflating the view.
So what could I be missing here that is preventing the fragment from displaying?
Your layout
<TextView android:id="#+id/section_label" android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ListView
android:id="#+id/list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scrollbars="vertical"
android:fadingEdge="vertical"
android:cacheColorHint="#00000000"
android:fastScrollEnabled="true"
android:padding="2dp">
</ListView>
Should be within a ViewGroup
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView android:id="#+id/section_label" android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ListView
android:id="#+id/list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scrollbars="vertical"
android:fadingEdge="vertical"
android:cacheColorHint="#00000000"
android:fastScrollEnabled="true"
android:padding="2dp">
</ListView>
</LinearLayout>
And you should return rootView in onCreateView().
Also, you might need to use replace method of Fragment Manager to replace one fragment with another, instead of add.