RecyclerView in DialogFragment not scrolling - android

I have a RecyclerView in a DialogFragment. Both the Dialog fragment and recyclerview show though when the recyclerview fills beyond the view capacity it does not scroll.
?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"
android:tag="FoodMenuTag"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.example.android.cop1803.MainActivity">
<View
android:id="#+id/divider3"
android:layout_width="1184dp"
android:layout_height="1dp"
android:layout_marginTop="#dimen/MarginTop_PDF_dividers"
android:layout_marginBottom="#dimen/MarginTop_PDF_dividers"
android:background="?android:attr/listDivider"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/kCal"
tools:layout_editor_absoluteX="8dp" />
<com.example.android.cop1803.MyRecyclerView
android:id="#+id/recycler_menuview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"
app:layout_constraintTop_toBottomOf="#id/divider3"
/>
Here's my Dialog Fragment:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.recyclerview_menu, container, false);
mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_menuview);
return view;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Bundle args = getArguments();
if(args != null) {
cartList = args.getParcelableArrayList("key");
MenuDialogFragmentAdapter adapter = new
MenuDialogFragmentAdapter(this.getActivity(), cartList);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setAdapter(adapter);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
}
}
#Override
public void onResume() {
// Get existing layout params for the window
ViewGroup.LayoutParams params = getDialog().getWindow().getAttributes();
// Assign window properties to fill the parent
params.width = WindowManager.LayoutParams.MATCH_PARENT;
params.height = WindowManager.LayoutParams.MATCH_PARENT;
getDialog().getWindow().setAttributes((android.view.WindowManager.LayoutParams) params);
// Call super onResume after sizing
super.onResume();}
Any help with getting this to work is much appreciated.
thanks,
Jim

It turned out I was not accounting for the full height of my recycler view. So it was actually working but the height was extending it beyond the bottom boundary. Once I made a few adjustments to the height it worked. Here's the XML that on landed on.
<com.example.android.cop1803.MyRecyclerView
android:id="#+id/recycler_menuview"
android:layout_width="match_parent"
android:layout_height="350dp"
android:layout_marginStart="8dp"
android:layout_marginBottom="8dp"
android:scrollbars="vertical"
app:layout_constraintVertical_bias="0.01"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/divider3" />
I don't like the height being a fixed value so I'll likely change via code.
thanks,
Jim

try adding nested scrolling to the recyclerview, see if its works.
recyclerView.setNestedScrollingEnabled(true);

Related

Recyclerview opens with the middle item and not from the top

This is my fragment where I have called the recycler view:
public class sgpa_frag extends Fragment {
//View view;
RecyclerView recyclerview;
adapter_sgpa ac;
ArrayList<POJO> sgpaArrayList;
public sgpa_frag() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_sgpa_frag, container, false);
recyclerview= (RecyclerView) view.findViewById(R.id.rc1);
sgpaArrayList= new ArrayList<>();
ac= new adapter_sgpa(sgpaArrayList);
recyclerview.setLayoutManager(new LinearLayoutManager(getContext(),RecyclerView.VERTICAL,true));
recyclerview.setAdapter(ac);
Fetchdata1();
return view;
}
private void Fetchdata1()
{
dbmanager db= new dbmanager(getContext());
Cursor cursor= db.fetch_data1();
if (cursor!= null){
// cursor.moveToFirst();
while (cursor.moveToNext()){
POJO pj= new POJO();
pj.setSname(cursor.getString(0));
pj.setSemester(cursor.getString(1));
pj.setSgpa(cursor.getString(2));
pj.setPercent(cursor.getString(3));
pj.setSchemes(cursor.getString(4));
sgpaArrayList.add(pj);
}
ac= new adapter_sgpa(sgpaArrayList);
}
}
}
This is my xml file:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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=".drawernav.bottom_navi.recycler_view.sgpa_frag">
<!-- TODO: Update blank fragment layout -->
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rc1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="60dp">
</androidx.recyclerview.widget.RecyclerView>
</FrameLayout>
I want my Recycler view to start displaying from the top item and not from the middle item . Can anyone tell me what changes should I make in my code ? Thanks in advance .
I mean to say that, it is like this:
And I want it to be like this:
You should set layout width and height of the recyclerview to match_parent.
The actual reason for your issue is probably the reverseLayout of your your linear layout manager. This has the effect as scrolling down the recyclerview.
Use this instead:
new LinearLayoutManager(getContext(),RecyclerView.VERTICAL,false)
Try adding
android:descendantFocusability="blocksDescendants"
to the recyclerview parent layout
Edit:
I think it is not a problem with RecyclerView instead if you are using a cordinator layout as root layout, try giving margin to your FrameLayout of 60
<!-- TODO: Update blank fragment layout -->
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rc1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop ="60dp" //approx for toolbar height
android:paddingBottom="60dp">
</androidx.recyclerview.widget.RecyclerView>
Add this into you code
mRecyclerView.smoothScrollToPosition(0);

Why is my DialogFragment not showing the custom layout?

I want to show a DialogFragment with no title, buttons, etc.(i.e, none of what is included in a typical Dialog) but just a ProgressBar spinner on a plain background. For a rough idea, the background's width matches that of the parent and spinner lies at the center of it. For this, I have a custom layout as follows:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
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">
<View
android:id="#+id/search_progress_alpha_indicator"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginLeft="16dp"
android:layout_marginStart="16dp"
android:layout_marginRight="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toTopOf="#+id/guideline3"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="#+id/guideline2"
android:background="#00ffffff"/>
<ProgressBar
android:id="#+id/search_tutors_progress_bar"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:visibility="gone"/>
<android.support.constraint.Guideline
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/guideline2"
app:layout_constraintGuide_percent="0.20"
android:orientation="horizontal"
tools:layout_editor_absoluteY="126dp"
tools:layout_editor_absoluteX="0dp" />
<android.support.constraint.Guideline
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/guideline3"
app:layout_constraintGuide_percent="0.80"
android:orientation="horizontal"
tools:layout_editor_absoluteY="378dp"
tools:layout_editor_absoluteX="0dp" />
</android.support.constraint.ConstraintLayout>
Here, View is the background on top of which the ProgressBar is supposed to spin.
But when I inflate this layout in the DialogFragment, it shows something completely different:
Here is the DialogFragment code:
public static class SearchIndicatorDialogFragment extends DialogFragment{
public static String FRAGMENT_TAG = "searchIndDiaFragTag";
private View alphaSearchIndicator;
private ProgressBar progressBar;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View dialogRootView = inflater.inflate(R.layout.fragment_search_dialog, container, false);
// Obtain the ProgressBar
progressBar = (ProgressBar) dialogRootView.findViewById(R.id.search_tutors_progress_bar);
// Obtain the Alpha search indicator
alphaSearchIndicator = dialogRootView.findViewById(R.id.search_progress_alpha_indicator);
return dialogRootView;
}
#Override
public void onStop() {
progressBar.setVisibility(View.GONE);
alphaSearchIndicator.setBackgroundColor(0x00ffffff);
super.onStop();
}
#Override
public void onResume() {
progressBar.setVisibility(View.VISIBLE);
alphaSearchIndicator.setBackgroundColor(0xA6ffffff);
super.onResume();
}
}
Why is it not showing my custom layout as intended?
EDIT: As an additional note, The problem in my case is that the background View is supposed to be occupying 60% area of screen(height wise) and for this I have constrained it in between the Guidelines. This is something, I am unable to achieve with other answers to similar questions regarding DialogFragment. Moreover, I would like to know, why does a DialogFragment doesn't display the correct by default in general?
If you change ConstraintLayout to Relative or Linear
This problem will be solved.
I was facing the same problem and I put my ConstraintLayout inside RelativeLayout and it worked.
I tried the same with LinearLayout but it didn't work.
Try this:
AlertDialog builder = new AlertDialog.Builder(this).create();
builder.setView(progressbar_id);
Window window = builder.getWindow();
window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT);
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
builder.show();
Put ConstraintLayout inside RelativeLayout. The issue will be solved.
try this
Window window = yourDialog.getWindow();
window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT);
window.setGravity(Gravity.CENTER);
or
int width = getResources().getDimensionPixelSize(R.dimen.popup_width);
int height = getResources().getDimensionPixelSize(R.dimen.popup_height);
getDialog().getWindow().setLayout(width, height);
Try changing
View dialogRootView = inflater.inflate(R.layout.fragment_search_dialog, container, false);
to
View dialogRootView = inflater.inflate(R.layout.fragment_search_dialog, container, true);
I suppose we are the ones responsible for attaching our layout file’s View to its root ViewGroup.

Adjusting DialogFragment Width and Height

I have problem with DialogFragmnt's Width and Height. Here is my class representing DialogFragmetn:
public class RecipeAddDialogFragment extends DialogFragment {
private ArrayList<RecipeDialogItem> recipeDialogItems;
private RecipeAddDialogAdapter recipeDialogAdapter;
private String recipeUniqueId;
private CoordinatorLayout coordinatorLayout;
private RecipeAddDialogFragment recipeDialogFragment;
#Override
public void onStart() {
super.onStart();
if (getDialog() == null) {
return;
}
int dialogWidth = 600;
int dialogHeight = 300;
getDialog().getWindow().setLayout(dialogWidth, dialogHeight);
getDialog().setTitle(getString(R.string.recipe_dialog_title));
}
#Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setStyle(DialogFragment.STYLE_NORMAL, R.style.AppTheme_DialogFragment);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.dialog_fragment, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
recipeDialogItems = new ArrayList<>();
RecyclerView dialogRecyclerView = (RecyclerView) view.findViewById(
R.id.dialog_recycler_view);
recipeDialogAdapter = new RecipeAddDialogAdapter(getContext(), recipeDialogItems,
R.layout.recipe_dialog_item);
recipeDialogAdapter.setRuidClRdf(recipeUniqueId, coordinatorLayout, recipeDialogFragment);
dialogRecyclerView.setHasFixedSize(true);
dialogRecyclerView.setAdapter(recipeDialogAdapter);
dialogRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
fillRecipeDialogArray();
}
private void fillRecipeDialogArray() {
String name = getString(R.string.add_to_favourites);
int icon = R.drawable.ic_heart_48dp;;
RecipeDialogItem dialogItem = new RecipeDialogItem();
dialogItem.setRowIcon(icon);
dialogItem.setRowOption(name);
recipeDialogItems.add(dialogItem);
recipeDialogAdapter.notifyDataSetChanged();
}
public void setReferences(String recipeUniqueId, CoordinatorLayout coordinatorLayout,
RecipeAddDialogFragment recipeDialogFragment) {
this.recipeUniqueId = recipeUniqueId;
this.coordinatorLayout = coordinatorLayout;
this.recipeDialogFragment = recipeDialogFragment;
}
}
Here is .xml which I infalte in this DialogFragment:
<?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:gravity="center|left"
android:padding="16dp"
android:orientation="horizontal"
android:clickable="true"
android:background="?android:attr/selectableItemBackground">
<!-- Option Icon -->
<ImageView
android:id="#+id/recipe_dialog_option_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="4dp"
android:tint="#color/primary" />
<!-- Text Option -->
<TextView
android:id="#+id/recipe_dialog_option_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:textColor="#color/primary_text" />
</LinearLayout>
The problem is that when I set it's size to 600 x 300 it is displayed fine in my 1280x720 device, but for example when my friend displays it on 1920x1080 resolution dialog is wrapped and only title is shown. List is wrapped and is not entire shown. Any idea how can I automaticly set it's size to fit every display and show entire dialog which is wrapped to it's content?
Edit
I have figured out to adjust the width of the DialogFragment to it's content like this:
getDialog().getWindow().setLayout(WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT);
getDialog().setTitle(getString(R.string.recipe_dialog_title));
However height is not working properly :/
In DialogFragment.onResume():
int width = getResources().getDimensionPixelSize(R.dimen.popup_width);
int height = getResources().getDimensionPixelSize(R.dimen.popup_height);
getDialog().getWindow().setLayout(width, height);
In the layout for the dialog:
android:layout_width="match_parent"
android:layout_height="match_parent"
Can take whole screen with:
getDialog().getWindow().setLayout(
getResources().getDisplayMetrics().widthPixels,
getResources().getDisplayMetrics().heightPixels
);
Hope that helps
Found the idea here How to set DialogFragment's width and height?

Set onClickListener on the RelativeLayout contained by CardView

I am trying to set the onClickListener on each of my CardView elements.
Since I was not able to set the onClickListener on the cards themselves (see here), I thought about setting it to the RelativeLayout contained by the cards. Right now I am using the native CardView library and applied this tutorial.
Here's my MainActivity's onCreate:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recycleCardView = (RecyclerView) findViewById(R.id.cardList);
recycleCardView.setHasFixedSize(true);
LinearLayoutManager llmanager = new LinearLayoutManager(this);
llmanager.setOrientation(LinearLayoutManager.VERTICAL);
recycleCardView.setLayoutManager(llmanager);
data = createList(9);
ContactAdapter ctadapter = new ContactAdapter(data);
//...
recycleCardView.setAdapter(ctadapter);
this is the item_card_view xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/card_view"
android:layout_width="match_parent" android:layout_height="match_parent"
card_view:cardCornerRadius="4dp"
android:layout_margin="5dp">
<RelativeLayout android:id="#+id/nativecardlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:background="?android:selectableItemBackground">
<!--some more layout-->
</RelativeLayout>
</android.support.v7.widget.CardView>
here's my ContactAdapter's onCreateViewHolder:
#Override
public ContactViewHolder onCreateViewHolder(final ViewGroup viewGroup, int i) {
View itemView = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.item_card_view, viewGroup, false);
RelativeLayout cardlayout = (RelativeLayout)
viewGroup.findViewById(R.id.nativecardlayout); //NullPointerException here
cardlayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(viewGroup.getContext(), "Clickable card", Toast.LENGTH_LONG).show();
}
});
return new ContactViewHolder(itemView);
}
My problem is that the RelativeLayout that I am trying to load, which is inside the cardview element, is null. Therefore I get a NullPointerException.
How can I set onClickListener on each RelativeLayout? Is this possible?
See below edit, its logical mistake:
RelativeLayout cardlayout = (RelativeLayout)itemView.findViewById(R.id.nativecardlayout);
You can set a listener to all Views. So it's possibile.
replace this
RelativeLayout cardlayout = (RelativeLayout)
viewGroup.findViewById(R.id.nativecardlayout);
with this
RelativeLayout cardlayout = (RelativeLayout)
itemView.findViewById(R.id.nativecardlayout);

Android, findViewById returns null

I'm writing some code for Android, the matter is that, when I call findViewById it returns me null, and I cannot understand why! I've been wasting my brain since yesterday, but I cannot figure out the solution. The goal is to set a layout as a header for a listView. Here is my code, respectively my header and my page:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/header"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp">
<TextView
android:text="#string/bydistance"
android:layout_gravity="left"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:textSize="13dp"
android:gravity="center_horizontal"/>
<TextView
android:text="#string/byactivity"
android:layout_gravity="right"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:textSize="13dp"
android:gravity="center_horizontal"/>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ff0000"
>
<ListView
android:id="#+id/parkList"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:divider="#android:color/transparent"
android:dividerHeight="5.0dp">
</ListView>
</LinearLayout>
And here my code where I call the addheaderView:
public class NearMeFragment extends Fragment implements View.OnClickListener{
private FragmentManager fragmentManager;
#Override
public void onCreate(Bundle savedBundle){
super.onCreate(savedBundle);
}
#Override
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedBundle) {
View v = inflater.inflate(R.layout.park_list, container, false);
//TODO remove
make_test(v, container);
return v;
}
public void openTest(View view){
new LiveComment().show(getChildFragmentManager(), "dialog");
}
public void onClick(View view){
if (fragmentManager == null)
fragmentManager = getChildFragmentManager();
//if (view.getId() == R.id.test){
fragmentManager.beginTransaction().add(new LiveComment(), "livecomment").commit();
}
private void make_test(View v, ViewGroup container) {
ListView listView = (ListView) v.findViewById(R.id.parkList);
Park[] list = new Park[3];
list[0] = new Park("parco a", "acquasparta", false, false, 1, 2, 3);
list[1]=new Park("parco b", "perugia", false, false, 1, 2, 3);
list[2]=new Park("parco b", "perugia", false, false, 1, 2, 3);
ParkListAdapter adapter = new ParkListAdapter(v.getContext(), R.layout.small_park_container,list);
LinearLayout header = (LinearLayout) container.findViewById(R.id.header);
listView.addHeaderView(header);
listView.setAdapter(adapter);
}
}
The error is given at
listView.addHeaderView(header)
R.id.header is inside v not inside container.
Change
LinearLayout header = (LinearLayout) container.findViewById(R.id.header);
with
LinearLayout header = (LinearLayout) v.findViewById(R.id.header);
about the ViewGroup container to doc says:
If non-null, this is the parent view that the fragment's UI should be
attached to. The fragment should not add the view itself, but this can
be used to generate the LayoutParams of the view.
Edit: Since your header view is in another Layout you have to inflate it too:
#Override
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedBundle) {
View v = inflater.inflate(R.layout.park_list, container, false);
View header = inflater.inflate(R.layout.headerlayout, null);
//TODO remove
make_test(v, header);
return v;
}
and
private void make_test(View v, View header) {
// your code
// you have to remove LinearLayout header = (LinearLayout) container.findViewById(R.id.header);
listView.addHeaderView(header);
listView.setAdapter(adapter);
}

Categories

Resources