I have a function which inflates a layout and is supposed to manipulate the views contained within the layout. The layout's base element is a ConstraintLayout.
The fragment:
public class HomeFragment extends Fragment {
...
public void myFunction() {
View v = getLayoutInflater().inflate(R.layout.fragment_home, null);
TextView t = (TextView) v.findViewById(R.id.my_text_view);
t.setText("Some other text"); // nothing happens
t.setTextColor(0xFF0000FF); // nothing happens
t.setBackgroundColor(0xFFFF0000); // nothing happens
Log.d("call", "myFunction() was called");
}
}
The layout:
<androidx.constraintlayout.widget.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/my_text_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#F0F0F0"
android:text="TextView"
android:textColor="#000"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout/>
The code compiles and runs successfully, but when I call myFunction() nothing happens to the TextView, while the log statement logs successfully. What am I doing wrong?
Related
I have created a tabLayout that swipes between two fragments using a viewPager2 + Fragment State Adapter
Within Fragment 2, I have a TextClock within a scroll view.
When I scroll down to the bottom of the page, it keeps jumping to the top if the page
Video link showing issue
Any help would be appreciated
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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"
tools:context=".BarcodeFragment">
Xml Code:
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
tools:layout_editor_absoluteY="104dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextClock
android:id="#+id/simpleTextClock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:format24Hour="HH : mm : ss"
android:textColor="#color/colorDark"
android:textScaleX=".94"
android:textSize="18sp"
android:textStyle="bold"
app:fontFamily="#font/tlcircular_bold"
app:layout_constraintBottom_toTopOf="#+id/box02"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/box02"
android:layout_width="329dp"
android:layout_height="283.99986dp"
android:layout_marginTop="450dp"
android:background="#drawable/box_rounded_ticket"
android:shadowColor="#00FF0A0A"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
Java Code:
</**
* A simple {#link Fragment} subclass.
*/
public class TicketFragment extends Fragment {
public TicketFragment() {
// Required empty public constructor
}
#RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_ticket, container, false);
return rootView;
}
}>
SOLVED
Whenever configuring the height / width of a TextClock - never use 'wrap_content'. I had to reverse engineer my entire app to find such such a simple problem.
My question is: why has this never been flagged before?!
I'm trying to display a list in a fixed size scrollview, at first it was the first items who weren't showing and I fixed it but now it's the last ones that aren't reachable.
Here is my xml code:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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:background="#color/colorPrimary"
tools:context=".ui.home.AperoDetailFragment">
<TextView
android:id="#+id/name_apero"
android:layout_width="156dp"
android:layout_height="53dp"
android:textSize="18sp"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
<TextView
android:id="#+id/date_apero"
android:layout_width="238dp"
android:layout_height="53dp"
android:textSize="18sp"
android:ems="10"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.907"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
<ScrollView
android:id="#+id/ingredient_apero"
android:layout_width="410dp"
android:layout_height="607dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/ingredient_title_apero"
app:layout_constraintVertical_bias="0.0">
<LinearLayout
android:id="#+id/vertical_layout_ingredient"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
</ScrollView>
<TextView
android:id="#+id/ingredient_title_apero"
android:layout_width="115dp"
android:layout_height="28dp"
android:text="Liste d'achat:"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.005"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.125" />
</androidx.constraintlayout.widget.ConstraintLayout>
and here is my java code to populate the list:
public class AperoDetailFragment extends Fragment {
private View root;
private Apero detailApero;
public AperoDetailFragment(Apero apero) {
this.detailApero = apero;
}
#Override
public View onCreateView(#NonNull final LayoutInflater inflater,
final ViewGroup container, Bundle savedInstanceState) {
root = inflater.inflate(R.layout.fragment_detail_apero, container, false);
TextView name = (TextView)root.findViewById(R.id.name_apero);
name.setText(detailApero.getName());
TextView date = (TextView)root.findViewById(R.id.date_apero);
date.setText(detailApero.getDate());
LinearLayout ll = (LinearLayout)root.findViewById(R.id.vertical_layout_ingredient);
LinearLayout a = new LinearLayout(root.getContext());
a.setOrientation(LinearLayout.VERTICAL);
for(int i = 0; i < 20; i++)
{
Button b = new Button(root.getContext());
b.setText("Button "+i);
a.addView(b);
}
ll.addView(a);
return root;
}
}
When I scroll I can reach the number 16 but not the other, it's like they are under the layout I don't really know how to explain better.
So the question is how can I scroll my list until the last items ?
There are a few issues with your code: first and foremost if you want to display data as a list you should use a RecyclerView instead of a ScrollView. ScrollViews are there to allow the content (or part of it) in your activity/fragment to be scrollable.
Second, it's not a good practice to set specific sizes to your views, especially when using ConstraintLayout.
Third, onCreateView is meant to be a method that will simply inflate your fragment's layout and return it as a View. For handling the UI, use onViewCreated. That way you will guarantee that your UI will never be handled before your fragment is actually attached to the activity.
So answering your question, use a RecyclerView to display your items as a list instead of the ScrollView and you'll be good to go from there
I want to display a Progressbar in my LoginFragment for testing purposes however after I connect my view variables in the OnCreateView Callback in my LoginFragment, my app shuts down and its due to:
Attempt to invoke virtual method 'void android.widget.ProgressBar.setVisibility(int)' on a null object reference
But what's driving me nuts is that this is the only View that throws a NPE, all my other views I am able to manipulate and reference without a problem. I also tried to use a Progressbar in the LoginActivity that hosts the LoginFragment and the Progressbar worked as expected, but why not in the fragment ??
I attached the code xml and fragment code corresponding to the LoginFragment
public class LoginFragment extends Fragment {
private AutoCompleteTextView name;
private EditText password;
private ProgressBar progressBar;
//......... Skipped For Brevity .........
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.login_fragment, container, false);
v.setBackgroundResource(R.drawable.album_jazz_blues);
name = v.findViewById(R.id.username);
password = v.findViewById(R.id.password);
progressBar = v.findViewById(R.id.progress_bar);
//progressBar.setVisibility(View.VISIBLE); <-------- THROWS NPE
return v;
}
}
XML:
<?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"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.constraint.ConstraintLayout
android:id="#+id/constraint_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/login_parent_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:padding="16dp"
android:orientation="vertical"
tools:layout_alignParentTop="true"
tools:layout_alignParentStart="true" >
<AutoCompleteTextView
android:id="#+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textEmailAddress"
android:hint="#string/email"
android:maxLines="1"
android:singleLine="true" />
<EditText
android:id="#+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/password"
android:inputType="textPassword"
android:maxLines="1"
android:singleLine="true"
tools:ignore="Autofill" />
</LinearLayout>
</android.support.constraint.ConstraintLayout>
<ProgressBar
style="#style/Widget.AppCompat.ProgressBar"
android:layout_gravity="center"
android:indeterminate="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/progress_bar">
</ProgressBar>
What Am I missing here ?
As Aaron in the comments pointed out, I had two different layout folders a normal folder and v-26 folder which did not necessarily mirror each other so what I did was assign the folders the exact same elements and attributes with their corresponding values with the exception of
EditTextandroid:importantForAutofill
autofill attribute, in v-26 android:importantForAutofill="no and in my regular layout folder tools:ignore="Autofill"
I am new to Android development and feel like this is a really trivial problem, but I cannot word it well enough to find a solution online, so I might as well ask the question here.
My goal is to create a reusable component that is essentially an expandable card like the one described here: https://material.io/design/components/cards.html#behavior.
To do it, I created a custom view that extends a CardView:
public class ExpandableCardView extends CardView {
public ExpandableCardView(Context context) {
super(context);
}
public ExpandableCardView(Context context, AttributeSet attrs) {
super(context, attrs);
// get custom attributes
TypedArray array = context.getTheme().obtainStyledAttributes(attrs, R.styleable.ExpandableCardView, 0, 0);
String heading = array.getString(R.styleable.ExpandableCardView_heading);
array.recycle();
// inflate the layout
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.expandable_card_view, this, true);
// set values
TextView headingTextView = findViewById(R.id.card_heading);
headingTextView.setText(heading.toUpperCase());
// set collapse/expand click listener
ImageView collapseExpandButton = findViewById(R.id.collapse_expand_card_button);
collapseExpandButton.setOnClickListener((View v) -> toggleCardBodyVisibility());
}
private void toggleCardBodyVisibility() {
LinearLayout description = findViewById(R.id.card_body);
ImageView imageButton = findViewById(R.id.collapse_expand_card_button);
if (description.getVisibility() == View.GONE) {
description.setVisibility(View.VISIBLE);
imageButton.setImageResource(R.drawable.ic_arrow_up);
} else {
description.setVisibility(View.GONE);
imageButton.setImageResource(R.drawable.ic_arrow_down);
}
}
}
And the layout:
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/expandable_card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="16dp"
android:animateLayoutChanges="true"
app:cardCornerRadius="4dp">
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/card_header"
android:padding="12dp"
android:layout_width="match_parent"
android:layout_height="48dp"
android:orientation="horizontal" >
<TextView
android:id="#+id/card_heading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:textColor="#color/colorPrimary"
android:layout_alignParentLeft="true"
android:text="HEADING"/>
<ImageView
android:id="#+id/collapse_expand_card_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
app:srcCompat="#drawable/ic_arrow_down"/>
</RelativeLayout>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/card_body"
android:padding="12dp"
android:layout_marginTop="28dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:visibility="gone" >
</LinearLayout>
</androidx.cardview.widget.CardView>
Ultimately I want to be able to use it like so in my activities, usually multiple instances per activity:
<xx.xyz.yy.customviews.ExpandableCardView
android:id="#+id/card_xyz"
android:layout_width="match_parent"
android:layout_height="match_parent"
custom_xxx:heading="SOME HEADING" >
<SomeView></SomeView>
</xx.xyz.yy.customviews.ExpandableCardView>
Where SomeView is any text, image, layout or another custom view altogether, typically with data bound from the activity.
How do I get it to render SomeView inside the card body? I want to take whatever child structure is defined within the custom view and show it in the card body when it is expanded. Hope I made it easy to understand.
I think that a better approach would be to define the layout that will be inserted into the CardView ("SomeView") in a separate file and reference it with a custom attribute like this:
<xx.xyz.yy.customviews.ExpandableCardView
android:id="#+id/card_xyz"
android:layout_width="match_parent"
android:layout_height="match_parent"
custom_xxx:heading="SOME HEADING"
custom_xxx:expandedView="#layout/some_view"/>
I'll explain my rationale at the end, but let's look at an answer to your question as stated.
What you are probably seeing with your code is SomeView and expandable_card_view appearing all at once in the layout. This is because SomeView is implicitly inflated with the CardView and then expandable_card_view is added through an explicit inflation. Since working with layout XML files directly is difficult, we will let the implicit inflation occur such that the custom CardView just contains SomeView.
We will then remove SomeView from the layout, stash it, and insert expandable_card_view in its place. Once this is done, SomeView will be reinserted into the LinearLayout with the id card_body. All this has to be done after the completion of the initial layout. To get control after the initial layout is complete, we will use ViewTreeObserver.OnGlobalLayoutListener. Here is the updated code. (I have removed a few things to simplify the example.)
ExpandableCardView
public class ExpandableCardView extends CardView {
public ExpandableCardView(Context context) {
super(context);
}
public ExpandableCardView(Context context, AttributeSet attrs) {
super(context, attrs);
// Get control after layout is complete.
getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
// Remove listener so it won't be called again
getViewTreeObserver().removeOnGlobalLayoutListener(this);
// Get the view we want to insert into the LinearLayut called "card_body" and
// remove it from the custom CardView.
View childView = getChildAt(0);
removeAllViews();
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.expandable_card_view, ExpandableCardView.this, true);
// Insert the view into the LinearLayout.
((LinearLayout) findViewById(R.id.card_body)).addView(childView);
// And the rest of the stuff...
TextView headingTextView = findViewById(R.id.card_heading);
headingTextView.setText("THE HEADING");
// set collapse/expand click listener
ImageView collapseExpandButton = findViewById(R.id.collapse_expand_card_button);
collapseExpandButton.setOnClickListener((View v) -> toggleCardBodyVisibility());
}
});
}
private void toggleCardBodyVisibility() {
LinearLayout description = findViewById(R.id.card_body);
ImageView imageButton = findViewById(R.id.collapse_expand_card_button);
if (description.getVisibility() == View.GONE) {
description.setVisibility(View.VISIBLE);
imageButton.setImageResource(R.drawable.ic_arrow_up);
} else {
description.setVisibility(View.GONE);
imageButton.setImageResource(R.drawable.ic_arrow_down);
}
}
}
expandable_card_view.java
The CardView tag is changed to merge to avoid a CardView directly nested within a CardView.
<merge
android:id="#+id/expandable_card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="16dp"
android:animateLayoutChanges="true"
app:cardCornerRadius="4dp">
<RelativeLayout
android:id="#+id/card_header"
android:padding="12dp"
android:layout_width="match_parent"
android:layout_height="48dp"
android:orientation="horizontal" >
<TextView
android:id="#+id/card_heading"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:textColor="#color/colorPrimary"
android:layout_alignParentLeft="true"
android:text="HEADING"/>
<ImageView
android:id="#+id/collapse_expand_card_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
app:srcCompat="#drawable/ic_arrow_down"/>
</RelativeLayout>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/card_body"
android:padding="12dp"
android:layout_marginTop="28dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:visibility="gone" >
</LinearLayout>
</merge>
activity_main.xml
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.example.customcardview.ExpandableCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/imageView"
android:layout_width="100dp"
android:layout_height="100dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/ic_android" />
<TextView
android:id="#+id/childView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Say my name."
android:textSize="12sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/imageView" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.example.customcardview.ExpandableCardView>
</LinearLayout>
So, why do I suggest that you use a custom attribute to include SomeView in the layout as I identified at the beginning? In the way outlined above, SomeView will always be inflated and there is some effort to switch the layout around although SomeView may never be shown. This would be expensive if you have a lot of custom CardViews in a RecyclerView for instance. By using a custom attribute to reference an external layout, you would only need to inflate SomeView when it is being shown and the code would be a lot simpler and easier to understand. Just my two cents and it may not really matter depending upon how you intend to use the custom view.
This question already has answers here:
RecyclerView items with big empty space after 23.2.0
(5 answers)
Closed 3 months ago.
I'm making a ToDo list app, and while testing it, for some reason, a huge gap forms between the items whenever I try to scroll down. It always happens whenever I Drag and Drop the items, but I don't see any errors with my ItemTouchHelper adapter and callback class. It would be awesome if you can help me out.
Before:
After:
RecyclerAdapter.java
public class RecyclerAdapter extends
RecyclerView.Adapter<RecyclerAdapter.RecyclerVH> implements ItemTouchHelperAdapter{
private LayoutInflater layoutInflater;
ArrayList<Info> data;
Context context;
public RecyclerAdapter(Context context) {
layoutInflater = LayoutInflater.from(context);
this.context = context;
}
public void setData(ArrayList<Info> data) {
this.data = data;
notifyDataSetChanged();
}
#Override
public RecyclerVH onCreateViewHolder(ViewGroup viewGroup, int position) {
View view = layoutInflater.inflate(R.layout.custom_row, viewGroup, false);
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("R.A onClick Owen", "onClick method triggered");
}
});
RecyclerVH recyclerVH = new RecyclerVH(view);
return recyclerVH;
}
#Override
public void onBindViewHolder(RecyclerVH recyclerVH, int position) {
Log.d("RecyclerView", "onBindVH called: " + position);
final Info currentObject = data.get(position);
// Current Info object retrieved for current RecyclerView item - USED FOR DELETE
recyclerVH.listTitle.setText(currentObject.title);
recyclerVH.listContent.setText(currentObject.content);
/*recyclerVH.listTitle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Open new Activity containing note content
Toast.makeText(this, "Opening: " + currentObject.title, Toast.LENGTH_LONG).show();
}
});*/
}
public void deleteItem(int position) {
DBInfo dbInfo = new DBInfo(context);
dbInfo.deleteNote(data.get(position));
// Deletes RV item/position's Info object
data.remove(position);
// Removes Info object at specified position
notifyItemRemoved(position);
// Notifies the RV that item has been removed
}
#Override
public int getItemCount() {
return data.size();
}
// This is where the Swipe and Drag-And-Drog methods come into place
#Override
public boolean onItemMove(int fromPosition, int toPosition) {
// Swapping positions
// ATTEMPT TO UNDERSTAND WHAT IS GOING ON HERE
Collections.swap(data, fromPosition, toPosition);
notifyItemMoved(fromPosition, toPosition);
return true;
}
#Override
public void onItemDismiss(int position) {
// Deleting item from RV and DB
deleteItem(position);
}
class RecyclerVH extends RecyclerView.ViewHolder implements View.OnClickListener{
// OnClickListener is implemented here
// Can also be added at onBindViewHolder above
TextView listTitle, listContent;
public RecyclerVH(View itemView) {
super(itemView);
listTitle = (TextView) itemView.findViewById(R.id.title);
listContent = (TextView) itemView.findViewById(R.id.content);
listTitle.setOnClickListener(this);
}
#Override
public void onClick(View v) {
Toast.makeText(context, "Opening: Note" + getLayoutPosition(), Toast.LENGTH_SHORT).show();
// PS NEVER ADD listTitle VARIABLE AS PUBLIC VARIABLE ABOVE WHICH IS GIVEN VALUE AT ONBINDVH
// THIS IS BECAUSE THE VALUE WILL CHANGE IF ITEM IS ADDED OR DELETED
}
}
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:fab="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"
android:orientation="vertical"
android:weightSum="1">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/rounded_corners" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerList"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.melnykov.fab.FloatingActionButton
android:id="#+id/fab_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginBottom="16dp"
android:layout_marginRight="16dp"
android:layout_marginEnd="16dp"
android:gravity="bottom|end"
android:onClick="addNote"
android:src="#drawable/fab_ic_add"
fab:fab_colorNormal="#color/colorPrimary"
fab:fab_colorPressed="#color/colorPrimaryDark"
fab:fab_colorRipple="#color/colorPrimaryDark" />
</RelativeLayout>
</FrameLayout>
</LinearLayout>
custom_row.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/main"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="8dp"
android:text="#string/test"
android:textSize="18sp"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/main"
android:paddingLeft="8dp">
<TextView
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/test"
android:textSize="15sp" />
</LinearLayout>
</RelativeLayout>
Thank you so much to whoever can help me out. I am pulling my hair out as I type.
EDIT: I have confirmed that it is not my ItemTouchHelper class that's the problem. (Tried running without it being called, problem still occurs.)
Also, it seems that when a dialog is shown and the keyboard brought up, the RecyclerView in the background resolves the problem by itself. After dialog is removed, the problem repeats (i.e. Scrolling puts massive space between items)
change in Recycler view match_parent to wrap_content:
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
Also change in item layout xml
Make parent layout height match_parent to wrap_content
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
This happened to me many times!
All you need to do is... make layout_height of row file wrap_content and your problem solved..
android:layout_height="wrap_content"
Happy coding!
Its because you are using match_parent in height of root view of the row item in your vertically oriented listview/recyclerview. When you use that the item expands completely wrt to its parent.
Use wrap_content for height when the recyclerview is vertically oriented and for width when it is horizantally oriented.
Avoid taking the view in item layout with a container like this:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data/>
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:listPreferredItemHeight"
android:textAppearance="?android:attr/textAppearanceMedium" />
</android.support.constraint.ConstraintLayout>
</layout>
as in this case match_parent will do its work and the problem will still remain! Rather take it like this:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data/>
<TextView
android:id="#+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:listPreferredItemHeight"
android:textAppearance="?android:attr/textAppearanceMedium" />
</layout>
[Note: Above code has data binding attached to it, don't use <layout> & <data> tags if not using data binding]
Other than this, if you must use any view group containers, than take a look the height and width attributes in the container, and try change those from match_parent to wrap_content. That should resolve the issue. For more transparency, one can try giving background colours and see through it to identify actual problem.
Just for the record: Since in my case we had to implement some "superfancy UI" with overlapping RecyclerView and blur effect toolbar, I had to get rid of clipToPadding="false" within RecyclerView-xml.
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="#dimen/height_toolbar"
android:paddingBottom="#dimen/height_bottom_bar_container"
//android:clipToPadding="false" <-- remove this flag!
android:scrollbars="vertical"
/>
paddingTopand paddingBottom worked, but we replaced it with some GapViews(empty views, with height of paddingTop and paddingBottom)
if someone is using | recyclerViewObject.setHasFixedSize(true);
try removing it, It was causing the issue in my case.
You can try setting your Viewgroup holding the recyclerview to wrap content
i have this problem and i just use
android:layout_height="wrap_content"
for parent of every item.