Android implement a progressBar with two clip textview on it - java

I am going to implement a progress bar with two clip textview on it.
Something like:
I use some trick (using paddingEnd/paddingStart, back/front textview to achieve the clip effect for textview) to implement it:
// part of activity
TextView leftFrontText;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View view = View.inflate(this, R.layout.test_page_layout, containerLayout);
View progressBar = view.findViewById(R.id.progress_bar);
leftFrontText = view.findViewById(R.id.left_front_textview);
int progress = 59;
ValueAnimator va = ValueAnimator.ofFloat(0f, progress);
int mDuration = 1000;
va.setDuration(mDuration);
va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
float value = (float)animation.getAnimatedValue();
setViewWidth(progressBar, (int)value);
setLeftFrontTextViewPadding((int)value);
}
});
// va.addListener(new Animator.AnimatorListener() {
// #Override
// public void onAnimationStart(Animator animation) {
//
// }
//
// #Override
// public void onAnimationEnd(Animator animation) {
// setLeftFrontTextViewPadding(progress);
// }
//
// #Override
// public void onAnimationCancel(Animator animation) {
//
// }
//
// #Override
// public void onAnimationRepeat(Animator animation) {
//
// }
// });
va.start();
}
private void setViewWidth(View view, int dp) {
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
layoutParams.width = ThemeUtil.dpToPx(this, dp);
view.setLayoutParams(layoutParams);
}
private void setLeftFrontTextViewPadding(int progressBarDp) {
int marginStart = ThemeUtil.dpToPx(TestPageActivity.this, 12);
leftFrontText.post(new Runnable() {
#Override
public void run() {
int textViewLength = leftFrontText.getWidth();
int progressbarDistance = ThemeUtil.dpToPx(TestPageActivity.this, progressBarDp);
if (textViewLength >= 0) {
int padding = marginStart + textViewLength - progressbarDistance;
leftFrontText.setPadding(0, 0, padding > 0 ? -padding : 0, 0);
}
}
});
}
And the layout is:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="28dp"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#drawable/rounded_corner_bg_for_cashlfow_homepage_category_cell"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
>
<TextView
android:id="#+id/left_bottom_textview"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:gravity="center_vertical"
android:text="Entertatinment"
android:textSize="#dimen/main_text_size"
android:maxLines="1"
android:ellipsize="end"
android:textColor="#color/grey1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="12dp"
/>
<View
android:id="#+id/progress_bar"
android:layout_width="10dp"
android:layout_height="match_parent"
android:background="#drawable/rounded_corner_front_progreebar_homepage_category_cell"
app:layout_constraintStart_toStartOf="parent"
/>
<TextView
android:id="#+id/left_front_textview"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:gravity="center_vertical|start"
android:text="Entertatinment"
android:textSize="#dimen/main_text_size"
android:maxLines="1"
android:ellipsize="end"
android:textColor="#color/white"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="12dp"
/>
<TextView
android:id="#+id/right_bottom_amount_textview"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:gravity="center_vertical|end"
android:text="$0 / $0"
android:textSize="#dimen/main_text_size"
android:maxLines="1"
android:textColor="#color/white"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="12dp"
/>
<TextView
android:id="#+id/right_front_amount_textview"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:gravity="center_vertical|end"
android:text="$0 / $0"
android:textSize="#dimen/main_text_size"
android:maxLines="1"
android:textColor="#color/black1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="12dp"
android:paddingStart="0dp"
/>
</android.support.constraint.ConstraintLayout>
When I run this code, it almost achieved the effect I want. But it has one issue. Textview keeps flashing while doing animation, and when animation finished, the color of textview sometime turn all white.
I think there may be something wrong in leftFrontText.post() of setLeftFrontTextViewPadding, like how I get width of textview. But I can't be quite sure. Can anyone show me the right way to do this? Or any other better way to implement this kind of progress bar.

Why not try this approach and leverage the power of ConstraintLayout as your progressBar:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/parentview"
android:layout_width="360dp"
android:layout_height="28dp"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#ddddff"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp">
<TextView
android:id="#+id/left_bottom_textview"
android:layout_width="180dp"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:text="Entertainment"
android:maxLines="1"
android:ellipsize="end"
android:textColor="#404040"
app:layout_constraintStart_toStartOf="parent"/>
<TextView
android:id="#+id/right_front_amount_textview"
android:layout_width="180dp"
android:layout_height="0dp"
android:gravity="center_vertical|end"
android:text="$0 / $0"
android:maxLines="1"
android:textColor="#color/black"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<android.support.constraint.ConstraintLayout
android:id="#+id/progress_bar"
android:layout_width="50dp"
android:layout_height="match_parent"
app:layout_constraintStart_toStartOf="parent"
android:background="#004090">
<TextView
android:id="#+id/left_front_textview"
android:layout_width="180dp"
android:layout_height="wrap_content"
android:text="Entertainment"
android:singleLine="true"
android:textColor="#fff"
android:ellipsize="none"
android:layout_paddingStart="12dp"
android:layout_paddingLeft="12dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
<TextView
android:id="#+id/right_bottom_amount_textview"
android:layout_width="180dp"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:gravity="center_vertical|end"
android:text="$0 / $0"
android:layout_alignRight="#id/left_front_textview"
android:textColor="#ffffff"
android:layout_paddingEnd="12dp"
android:layout_paddingRight="12dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="#id/left_front_textview"/>
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
So basically we would have:
The Parent layout (parentview): having a fixed layout_width 360dp and contains the initial Grey TextViews
The Progress layout (progress_bar): also having a fixed size 360dp and contains the front White TextViews
Hence we overlay the Progress layout (progress_bar) ontop of its parent layout and increase or decrease the layout_width to simulate a progress without flickering:
The image below shows the progress layout having a static layout_width of 74dp; Also note that progress layout_width based on the example provided above can range from 1dp to max:360dp or otherwise 1% to 100% of parentview width.

Related

How to keep a moveable TextView inside an ImageView in android studio

I am trying to place a moveable TextView inside of an ImageView such that the TextView should listen to my touch movement and move accordingly but should remain within the borders of the ImageView.
I have the below XML code where I am using Github library ZoomageView:
`<?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=".ImageEditActivity"
android:background="#color/primary_dark">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/text_edit_tab"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:menu="#menu/text_edit_tab_menu"
app:itemIconTint="#drawable/icon_selector"
app:itemTextColor="#drawable/icon_selector"
android:elevation="5dp"
android:background="#color/colour_transparent"/>
<com.jsibbold.zoomage.ZoomageView
android:id="#+id/edit_image_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="#+id/text_edit_tab"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.5"
android:src="#mipmap/ic_launcher"
tools:layout_editor_absoluteX="100dp"
/>
<TextView
android:id="#+id/move_quote_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="#string/what_s_on_your_mind"
app:layout_constraintBottom_toTopOf="#+id/text_edit_tab"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:textColor="#color/teal_200"
android:textSize="16sp"
android:visibility="gone"/>
<View
android:id="#+id/blurred_background"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#color/colour_semi_transparent"
app:layout_constraintBottom_toTopOf="#id/text_edit_tab"
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="1.0" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/quote_text"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginHorizontal="30dp"
app:layout_constraintTop_toTopOf="#id/edit_image_view"
app:layout_constraintBottom_toBottomOf="#id/edit_image_view"
android:hint="#string/what_s_on_your_mind"
android:textColorHint="#color/white"
android:textAlignment="viewStart"
android:paddingHorizontal="10dp"
android:textSize="18sp"
android:paddingVertical="10dp"
android:background="#drawable/quote_text_background"
/>
<Button
android:id="#+id/done_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="#color/primary_red"
android:text="#string/next"
android:textColor="#color/white"
android:textSize="14sp"
android:layout_marginBottom="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/quote_text"
android:layout_marginTop="20dp"
android:layout_marginEnd="20dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>
I am using the below function - isQuoteInsideImage() to get the location of my TextView w.r.t the ImageView :
`private boolean isQuoteInsideImage(float x, float y, ZoomageView view) {
int[] location = new int[2];
view.getLocationOnScreen(location);
int viewX = location[0];
int viewY = location[1];
return ((x > viewX && x < (viewX + view.getWidth())) && (y > viewY && y < (viewY + view.getHeight())));
}`
And the below code : `
moveQuoteText.setOnTouchListener((view, motionEvent) -> {
if (motionEvent.getAction() == MotionEvent.ACTION_MOVE) {
if (isQuoteInsideImage(moveQuoteText.getX(), moveQuoteText.getY(), editZoomageView)) {
view.setX(motionEvent.getRawX() - view.getWidth());
view.setY(motionEvent.getRawY() - view.getHeight());
}
}
return true;
});`
However, whenever I am trying to drag the TextView, the TextView goes out of the lower bounds and the Left Bounds. It however remains restricted at some distance from the upper bound.
Upper bound
Lower bound
What am I doing wrong and what should be done to make the TextView remain in the bound of the ImageView?

Add a GIF in Android Studio Java

I need to add a GIF in my code snippet on the screen, i need it to be played continuously
and without stopping I saw many blogs, QnAs on google but I didn't find the answer, here goes my MainActivity.java(Showing MainActivity.class as it was not allowing me to post the whole code) -
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView lightUp = findViewById(R.id.lightUp4);
Button unLight = findViewById(R.id.unlight);
ImageView AgarbattiBtn = findViewById(R.id.agarbattiBtn);
MediaPlayer Sound_matchstick = MediaPlayer.create(this, R.raw.matchstick);
MediaPlayer Om_Bhur = MediaPlayer.create(this, R.raw.om_bhur);
lightUp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ImageView image1 = findViewById(R.id.diya);
image1.setImageResource(R.drawable.lit_diya);
lightUp.setVisibility(View.INVISIBLE);
Sound_matchstick.start();
if(lightUp.getVisibility() == View.INVISIBLE && AgarbattiBtn.getVisibility() == View.INVISIBLE){
Om_Bhur.start();
}
}
});
unLight.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ImageView image2 = findViewById(R.id.diya);
image2.setImageResource(R.drawable.not_lit_diya);
AgarbattiBtn.setVisibility(View.VISIBLE);
findViewById(R.id.agrabatti).setVisibility(View.INVISIBLE);
lightUp.setVisibility(View.VISIBLE);
Om_Bhur.stop();
}
});
AgarbattiBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AgarbattiBtn.setVisibility(View.INVISIBLE);
findViewById(R.id.agrabatti).setVisibility(View.VISIBLE);
if(lightUp.getVisibility() == View.INVISIBLE && AgarbattiBtn.getVisibility() == View.INVISIBLE){
Om_Bhur.start();
}
}
});
}
}
This is my activity_main.xml -
<?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=".MainActivity">
<ImageView
android:id="#+id/mandir"
android:layout_width="508dp"
android:layout_height="521dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.473"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.39"
app:srcCompat="#mipmap/mandir" />
<Button
android:id="#+id/unlight"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Close"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.06"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.96" />
<ImageView
android:id="#+id/diya"
android:layout_width="78dp"
android:layout_height="62dp"
app:layout_constraintBottom_toBottomOf="#+id/mandir"
app:layout_constraintEnd_toEndOf="#+id/mandir"
app:layout_constraintHorizontal_bias="0.4"
app:layout_constraintStart_toStartOf="#+id/mandir"
app:layout_constraintTop_toTopOf="#+id/mandir"
app:layout_constraintVertical_bias="0.75"
app:srcCompat="#mipmap/not_lit_diya" />
<ImageView
android:id="#+id/lightUp4"
android:layout_width="142dp"
android:layout_height="70dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="#+id/unlight"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0"
app:srcCompat="#drawable/matchstick" />
<ImageView
android:id="#+id/imageView4"
android:layout_width="68dp"
android:layout_height="81dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.24"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.55"
app:srcCompat="#drawable/krishna_ji" />
<ImageView
android:id="#+id/imageView5"
android:layout_width="78dp"
android:layout_height="84dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.76"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.55"
app:srcCompat="#drawable/mata_rani" />
<ImageView
android:id="#+id/agarbattiBtn"
android:layout_width="80dp"
android:layout_height="105dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.86"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0"
app:srcCompat="#drawable/agarbatti" />
<ImageView
android:id="#+id/agrabatti"
android:layout_width="86dp"
android:layout_height="104dp"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.56"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.59000003"
app:srcCompat="#drawable/agarbatti" />
</androidx.constraintlayout.widget.ConstraintLayout>
Thanks in advance...
You can use 3rd party view library like this because custom solutions are too complicated to write from what I've seen.
Just import it into you project
dependencies {
implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.19'
}
And use:
<pl.droidsonroids.gif.GifImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/src_anim"
android:background="#drawable/bg_anim"
/>
If drawables declared by android:src and/or android:background are GIF
files then they will be automatically recognized as GifDrawables and
animated.
There are methods for GIF control such as:
stop() - stops the animation, can be called from any thread
start() - starts the animation, can be called from any thread
isRunning() - returns whether animation is currently running or
not reset() - rewinds the animation, does not restart stopped one
setSpeed(float factor) - sets new animation speed factor, eg.
passing 2.0f will double the animation speed seekTo(int position)
seeks animation (within current loop) to given position (in milliseconds)
getDuration() - returns duration of one loop of the animation
getCurrentPosition() - returns elapsed time from the beginning of a
current loop of animation
Please refer to the docs for more info :)

Constraint layout has space bottom and top

I'm building an app using Constraint layout, but it has extra space bottom and top. I can't find where they come from. I checked maybe ten times from top to bottom all code but there is no margin or padding or anything else for it.
<?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:id="#+id/relativeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/black"
android:paddingLeft="0dp"
android:paddingTop="0dp"
android:paddingRight="0dp"
android:paddingBottom="0dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/Brand"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="#id/guideline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="#+id/brandname"
style="#style/viewParent.headerText"
android:text="Did"
android:textColor="#color/white" />
<TextView
android:id="#+id/brandname2"
style="#style/viewParent.headerText2"
android:layout_toRightOf="#id/brandname"
android:text="You"
android:textColor="#color/yellow" />
<TextView
style="#style/viewParent.headerText2"
android:layout_toRightOf="#id/brandname2"
android:text="Know!"
android:textColor="#color/red"
android:textStyle="bold|italic" />
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/container_main"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_margin="4dp"
android:background="#drawable/card_bg"
android:paddingLeft="16dp"
android:paddingRight="16dp"
app:layout_constraintBottom_toTopOf="#id/guideline2"
app:layout_constraintEnd_toEndOf="#id/guidelineyazisag"
app:layout_constraintStart_toStartOf="#id/guidelineyazisol"
app:layout_constraintTop_toBottomOf="#id/guideline">
<TextView
android:id="#+id/activity_main_text_view_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="simple Title Text"
android:textColor="#5E4C4C"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/activity_main_did_u_know"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="Category"
android:textColor="#5E4C4C"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.core.widget.NestedScrollView
android:id="#+id/scrollview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:fillViewport="true"
app:layout_constraintBottom_toTopOf="#id/activity_main_image_view"
app:layout_constraintTop_toBottomOf="#id/activity_main_did_u_know">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="#id/activity_main_image_view"
app:layout_constraintTop_toBottomOf="#id/activity_main_did_u_know">
<TextView
android:id="#+id/factTextView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="8dp"
android:gravity="center_vertical|center_horizontal"
android:lineSpacingExtra="8dp"
android:padding="10dp"
android:text="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged."
android:textColor="#000000"
android:textSize="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
<ImageView
android:id="#+id/activity_main_image_view"
android:layout_width="30dp"
android:layout_height="40dp"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:clickable="true"
android:src="#drawable/ic_share_black_24dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/scrollview" />
<ImageView
android:id="#+id/activity_main_fav_button"
android:layout_width="30dp"
android:layout_height="40dp"
android:layout_margin="16dp"
android:clickable="true"
android:src="#drawable/ic_favorite_border_black_24dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#id/scrollview" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/LeftRight"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="#id/adView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/guideline2">
<ImageView
android:id="#+id/activity_main_left_button"
android:layout_width="60dp"
android:layout_height="60dp"
android:clickable="true"
android:src="#drawable/ic_previous"
android:elevation="3dp"
android:background="#drawable/okarka"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#id/guideline3"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="#+id/activity_main_right_button"
android:layout_width="60dp"
android:layout_height="60dp"
android:clickable="true"
android:src="#drawable/ic_next"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
android:background="#drawable/okarka"
app:layout_constraintStart_toEndOf="#+id/guideline3"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideline3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.gms.ads.AdView xmlns:ads="http://schemas.android.com/apk/res-auto"
android:id="#+id/adView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
ads:adSize="SMART_BANNER"
ads:adUnitId="ca-app-pub-3940256099942544/6300978111"
ads:layout_constraintBottom_toBottomOf="parent"
ads:layout_constraintLeft_toLeftOf="parent"
ads:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/LeftRight" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.076" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guideline2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.7" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guidelineyazisol"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.07" />
<androidx.constraintlayout.widget.Guideline
android:id="#+id/guidelineyazisag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.93" />
</androidx.constraintlayout.widget.ConstraintLayout>
I tried adding guidelines to 0 points in the bottom but it also starts in that space. I gave -(minus) values to margin and padding but doesn't work. I don't know what else to do. You can see from screenshots how it looks.
public class MainActivity extends AppCompatActivity {
private ColorWheel colorWheel = new ColorWheel();
private TextView factTextView;
private TextView textViewId;
private TextView textViewTableName;
ImageView tableImageView;
AdView adView;
ImageView shareImageView;
ImageView favImageView;
float x1,x2,y1,y2;
int i = 1;
int adCounter = 0;
private ConstraintLayout constraintLayout;
String fact;
ArrayList<Fact> favList = new ArrayList<>();
private InterstitialAd mInterstitial;
AdRequest interAdRequest;
int favId;
String favTable;
Typeface typeface;
List<Fact> mData;
private DatabaseFacts db;
GradientDrawable shape;
#SuppressLint({"ClickableViewAccessibility", "SetTextI18n"})
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
db = new DatabaseFacts(this);
db.copyDbIfNotExists();
shape = new GradientDrawable();
shape.setCornerRadius(40);
mData = new ArrayList<>();
MobileAds.initialize(this, "ca-app-pub-2469721886989416~7390658870");
adView = findViewById(R.id.adView);
AdRequest bannerAdRequest = new AdRequest.Builder().build();
adView.loadAd(bannerAdRequest);
interAdRequest = new AdRequest.Builder().build();
mInterstitial = new InterstitialAd(this);
mInterstitial.setAdUnitId("ca-app-pub-2469721886989416/9441000894");
mInterstitial.loadAd(interAdRequest);
factTextView = findViewById(R.id.factTextView);
constraintLayout = (ConstraintLayout) findViewById(R.id.container_main);
textViewId = findViewById(R.id.activity_main_text_view_id);
favImageView = findViewById(R.id.activity_main_fav_button);
shareImageView = findViewById(R.id.activity_main_image_view);
textViewTableName = findViewById(R.id.activity_main_did_u_know);
// tableImageView = findViewById(R.id.img_user);
// if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
// typeface = getResources().getFont(R.font.sourceserifproregular);
// }
factTextView.setTypeface(typeface);
Intent intent = getIntent();
final int choice = intent.getIntExtra("choice",0);
switch (choice) {
case 1:
textViewTableName.setText("General Facts");
factTextView.setText(db.getFact((readFromShared("defaultKey") - 1), DatabaseFacts.TABLE_GENERAL_NAME).getFact());
textViewId.setText("Fact " + (readFromShared("defaultKey") - 1) + " of " + db.getFactsCount(DatabaseFacts.TABLE_GENERAL_NAME));
if (db.getFact((readFromShared("defaultKey") - 1), DatabaseFacts.TABLE_GENERAL_NAME).isFavorite() == 0) {
favImageView.setImageResource(R.drawable.ic_favorite_border_black_24dp);
} else {
favImageView.setImageResource(R.drawable.ic_favorite_black_24dp);
}
ImageView leftClick = (ImageView) findViewById(R.id.activity_main_left_button);
leftClick.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
leftClickMethod("defaultKey", DatabaseFacts.TABLE_GENERAL_NAME);
}
});
ImageView rightClick = (ImageView) findViewById(R.id.activity_main_right_button);
rightClick.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
rightClickMethod("defaultKey",DatabaseFacts.TABLE_GENERAL_NAME);
return;
}
});
favImageView.setOnClickListener(v -> handleFavorites("defaultKey", DatabaseFacts.TABLE_GENERAL_NAME));
break;
Remove app:layout_constraintBottom_toTopOf="#id/guideline" from Brand and app:layout_constraintTop_toBottomOf="#id/LeftRight" from adView. You can't put constraints for Top and Bottom because it will center your View between those two constraints. Same about left and right (start, end), but you have match_parent here, so this problem doesn't occur (visualy - if you set wrap_content, view will go to the center too).

Gone elements in ConstraintLayout leaves ghost space

So I have a layout file for a RecycleView which has expandable/collapsible viewholders.
Clicking on the header would expand/collapse the extra data. Everything looks fine in the editor. However, it would have a ghost space similar to layout_marginBottom.
First loaded appearance
Expanded
Collapsed correctly
So the editor would only display the ViewHolder as Figure 2 and 3.
However when running on a device, it would first display Figure 1, then after clicking on it to expand it, it would display Figure 2. Collapsing it once again would display Figure 3 instead of Figure 1. It would continue to display the correct figures (2 and 3).
The extra contents in Figure 2 have common parents with the header which is a ConstraintLayout.
This would happen regardless of the GONE specifiers: Programmatically or XML
Using activity.runOnUIThread would not help. Using a new Handler().onPostDelayed would only be worse as would display Figure 1 but with more unwanted space, as much as Figure 2, only without the extra info.
Here's the XML file:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
app:cardCornerRadius="10dp">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:id="#+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/validity"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0">
<ImageButton
android:id="#+id/expand"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:layout_marginRight="8dp"
android:layout_marginEnd="8dp"
app:srcCompat="#drawable/ic_right" />
<TextView
android:id="#+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ellipsize="end"
android:maxLines="1"
android:textColor="#color/textDark" />
</LinearLayout>
<View
android:id="#+id/divider"
android:layout_width="0dp"
android:layout_height="2dp"
android:layout_marginEnd="16dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginStart="16dp"
android:background="#color/colorSecondaryDark"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/header" />
<TextView
android:id="#+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="8dp"
android:layout_marginStart="10dp"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toStartOf="#+id/size"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/divider" />
<TextView
android:id="#+id/size"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/divider" />
<TextView
android:id="#+id/amount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="8dp"
android:layout_marginStart="10dp"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toStartOf="#+id/validity"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/date" />
<LinearLayout
android:id="#+id/validity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="8dp"
android:gravity="center_vertical"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/size">
<ImageView
android:id="#+id/help"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_weight="1"
android:contentDescription="#string/backup_layout_help_desc"
app:srcCompat="#drawable/ic_help" />
<TextView
android:id="#+id/invalid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/backup_layout_invalid"
android:textAllCaps="true"
android:textColor="#color/red" />
</LinearLayout>
<TextView
android:id="#+id/passwords"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:layout_marginStart="10dp"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/amount" />
<Button
android:id="#+id/delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="8dp"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:background="#android:color/transparent"
android:text="#string/backup_layout_delete"
android:textColor="#color/red"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="#+id/importshare"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/passwords"
app:layout_constraintVertical_bias="1.0" />
<LinearLayout
android:id="#+id/importshare"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="10dp"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#+id/validity"
app:layout_constraintVertical_bias="1.0">
<Button
android:id="#+id/commit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#android:color/transparent"
android:text="Import"
android:textColor="#color/yellow" />
<ImageButton
android:id="#+id/share"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#android:color/transparent"
android:contentDescription="Share"
android:padding="10dp"
app:srcCompat="#drawable/ic_share" />
</LinearLayout>
</android.support.constraint.ConstraintLayout>
And the ViewHolder (cut to show relevant parts):
public ViewHolder(View itemView, Context context) {
super(itemView);
Amount = itemView.findViewById(R.id.amount);
Date = itemView.findViewById(R.id.date);
Delete = itemView.findViewById(R.id.delete);
Divider = itemView.findViewById(R.id.divider);
ExpandCollapse = itemView.findViewById(R.id.expand);
Import = itemView.findViewById(R.id.commit);
ImportShare = itemView.findViewById(R.id.importshare);
Header = itemView.findViewById(R.id.header);
Help = itemView.findViewById(R.id.help);
Passwords = itemView.findViewById(R.id.passwords);
Share = itemView.findViewById(R.id.share);
Size = itemView.findViewById(R.id.size);
Title = itemView.findViewById(R.id.title);
Validity = itemView.findViewById(R.id.validity);
Title.setTypeface(Typeface.createFromAsset(context.getAssets(), "cera.otf"));
Header.setOnClickListener(this);
onClick(Header);
}
#Override
public void onClick(View v) {
if (expanded) collapse();
else expand();
}
public void expand() {
ExpandCollapse.animate().rotation(90).start();
Date.setVisibility(View.VISIBLE);
Size.setVisibility(View.VISIBLE);
Amount.setVisibility(View.VISIBLE);
Passwords.setVisibility(View.VISIBLE);
Divider.setVisibility(View.VISIBLE);
Validity.setVisibility(valid ? View.INVISIBLE : View.VISIBLE);
Delete.setVisibility(View.VISIBLE);
ImportShare.setVisibility(View.VISIBLE);
expanded = true;
}
public void collapse() {
ExpandCollapse.animate().rotation(0).start();
Date.setVisibility(View.GONE);
Size.setVisibility(View.GONE);
Amount.setVisibility(View.GONE);
Passwords.setVisibility(View.GONE);
Divider.setVisibility(View.GONE);
Validity.setVisibility(View.GONE);
Delete.setVisibility(View.GONE);
ImportShare.setVisibility(View.GONE);
expanded = false;
}
Kotlin
I had a very similar issue when attempting to hide elements when the keyboard is open
What would happen is when you open the keyboard you would get two resizes, One adjustment for the opening and the keyboard and another for setting the views to gone. The problem is the second adjustment would only occur when another element requests a layout so your screen would jump around very noticeably twice
When keyboard open
When you tap or move another UI element
I have found a solution for this, but only when Window soft input mode = adjust resize
See below
class MainActivity : AppCompatActivity() {
private var activityHeight = 0
private var keyboardOpen = false
private var mainScreen : ConstraintLayout? = null
private var infoText : TextView? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_screen)
mainScreen = findViewById(R.id.mainConstraintLayout)
infoText = findViewById(R.id.mainInfoText)
//...
/* Capture initial screen size */
this#MainActivity.window.decorView.doOnNextLayout {
val displayFrame : Rect = Rect()
this#MainActivity.window.decorView.getWindowVisibleDisplayFrame(displayFrame)
activityHeight = displayFrame.height()
}
/* Check for keyboard open/close */
this#MainActivity.window.decorView.addOnLayoutChangeListener { v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom ->
val drawFrame : Rect = Rect()
this#MainActivity.window.decorView.getWindowVisibleDisplayFrame(drawFrame)
val currentSize = drawFrame.height()
if(keyboardOpen){
keyboardOpen = currentSize < activityHeight
if (!keyboardOpen){
infoText?.visibility = View.VISIBLE
}
}else {
keyboardOpen = currentSize < activityHeight
if(keyboardOpen) {
infoText?.visibility = View.GONE
/* Request a new layout on your base layout so screen adjusts correctly */
mainScreen?.requestLayout()
}
}
}
}
}

Expanding / Collapsing Cards in Recycler View sometimes result in whitespaces and drawing bugs

The Problem
I have a recycler view with card items. These card items contain only text and are expandable.It looks like this Collapsed Expanded
Now I expand and collapse one of them sometimes and scroll around and somehow there appears now more whitespace between the cards:
Whitespace between cards
Moreover, for cards with long text when I click to collapse them, this appears:
Big Cards
The Code
xml:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.ramotion.foldingcell.FoldingCell
android:id="#+id/folding_cell"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
app:backSideColor="#F5F5F5">
<FrameLayout
android:id="#+id/cell_content_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="300dp"
android:visibility="gone">
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:cardview="http://schemas.android.com/apk/res-auto"
xmlns:custom="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/movie_card2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:foreground="?attr/selectableItemBackground"
android:minHeight="300dp"
cardview:cardBackgroundColor="#color/card_background"
cardview:cardCornerRadius="1dp"
cardview:cardElevation="4dp"
cardview:cardUseCompatPadding="true">
<RelativeLayout
android:id="#+id/review_item2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:orientation="vertical">
<View
android:id="#+id/review_detail_header"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#color/material_red_400" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#id/review_detail_header"
android:layout_alignTop="#id/review_detail_header"
android:layout_centerHorizontal="true"
android:gravity="center"
android:text="Review Details"
android:textColor="#color/text_secondary" />
<ImageView
android:id="#+id/ic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/review_detail_header"
android:layout_marginTop="#dimen/material_layout_keylines_horizontal_margin"
android:adjustViewBounds="true"
android:paddingLeft="#dimen/material_layout_keylines_horizontal_margin"
android:paddingRight="#dimen/material_layout_keylines_horizontal_margin"
android:src="#drawable/ic_account_circle_white_24dp"
android:tint="#color/accent"
tools:ignore="ContentDescription" />
<com.mt.moviesiwanttowatch.ui.widget.TextViewRoboto
android:id="#+id/review_author2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/review_detail_header"
android:layout_gravity="center_vertical"
android:layout_marginTop="#dimen/material_layout_keylines_horizontal_margin"
android:layout_toRightOf="#id/ic"
android:textSize="14sp"
custom:robotoType="bold"
tools:text="User Name" />
<com.mt.moviesiwanttowatch.ui.widget.TextViewRoboto
android:id="#+id/review_body2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/review_author2"
android:layout_marginBottom="#dimen/material_layout_keylines_horizontal_margin"
android:layout_marginLeft="56dp"
android:layout_marginRight="24dp"
android:layout_marginTop="#dimen/material_layout_vertical_spacing_between_content_areas"
android:layout_weight="1"
android:ellipsize="none"
android:maxLines="100"
android:scrollHorizontally="false"
android:textSize="14sp"
custom:robotoType="regular"
tools:text="The movie's review goes here..." />
<com.mt.moviesiwanttowatch.ui.widget.TextViewRoboto
android:id="#+id/review_spoiler2"
style="#style/ReviewBodyStyle"
android:text="#string/reviews_alert"
android:textColor="#color/primary"
android:visibility="gone"
custom:robotoType="bold" />
<com.mt.moviesiwanttowatch.ui.widget.TextViewRoboto
android:id="#+id/review_time2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_below="#+id/review_body2"
android:layout_margin="#dimen/material_layout_keylines_horizontal_margin"
android:textSize="#dimen/material_layout_keylines_horizontal_margin"
android:visibility="gone"
custom:robotoType="regular"
tools:text="01 Jan 2016" />
</RelativeLayout>
</android.support.v7.widget.CardView>
</FrameLayout>
​
<FrameLayout
android:id="#+id/cell_title_view"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:cardview="http://schemas.android.com/apk/res-auto"
xmlns:custom="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/movie_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:foreground="?attr/selectableItemBackground"
cardview:cardBackgroundColor="#color/card_background"
cardview:cardCornerRadius="1dp"
cardview:cardElevation="4dp"
cardview:cardUseCompatPadding="true">
<RelativeLayout
android:id="#+id/review_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:orientation="vertical"
android:padding="#dimen/material_layout_keylines_horizontal_margin">
<ImageView
android:id="#+id/ic2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:adjustViewBounds="true"
android:src="#drawable/ic_account_circle_white_24dp"
android:tint="#color/accent"
tools:ignore="ContentDescription" />
<com.mt.moviesiwanttowatch.ui.widget.TextViewRoboto
android:id="#+id/review_author"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/material_layout_keylines_horizontal_margin"
android:layout_toRightOf="#+id/ic2"
custom:robotoType="bold"
android:textSize="14sp"
tools:text="User Name" />
<!-- Review open icon -->
<ImageView
android:id="#+id/review_open"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:adjustViewBounds="true"
android:src="#drawable/ic_open_in_new_white_24dp"
android:tint="#color/accent"
tools:ignore="contentDescription" />
<!-- Review Body -->
<com.mt.moviesiwanttowatch.ui.widget.TextViewRoboto
android:id="#+id/review_body"
style="#style/ReviewBodyStyle"
android:layout_marginLeft="40dp"
android:layout_marginRight="8dp"
android:layout_below="#+id/review_spoiler"
custom:robotoType="regular"
tools:text="The movie's review goes here..." />
<com.mt.moviesiwanttowatch.ui.widget.TextViewRoboto
android:id="#+id/review_spoiler"
style="#style/ReviewBodyStyle"
android:layout_below="#id/review_open"
android:text="#string/reviews_alert"
android:textColor="#color/primary"
android:layout_marginLeft="40dp"
android:layout_marginRight="8dp"
android:visibility="gone"
custom:robotoType="bold" />
<com.mt.moviesiwanttowatch.ui.widget.TextViewRoboto
android:id="#+id/review_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_below="#+id/review_body"
android:layout_margin="#dimen/material_layout_keylines_horizontal_margin"
android:textSize="#dimen/material_layout_keylines_horizontal_margin"
android:visibility="gone"
custom:robotoType="regular"
tools:text="01 Jan 2016" />
</RelativeLayout>
</android.support.v7.widget.CardView>
</FrameLayout>
</com.ramotion.foldingcell.FoldingCell>
</layout>
The adapter:
public class ReviewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public ArrayList<Review> reviewList;
public int foldingCellPosition = -1;
public FoldingCell currentFoldingCell;
// Constructor
public ReviewAdapter(ArrayList<Review> reviewList) {
this.reviewList = reviewList;
}
// RecyclerView methods
#Override
public int getItemCount() {
return reviewList.size();
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ViewGroup v = (ViewGroup) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_list_review, parent, false);
return new ReviewViewHolder(v);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
Review review = reviewList.get(position);
ReviewViewHolder holder = (ReviewViewHolder) viewHolder;
if (position == foldingCellPosition) {
holder.binding.foldingCell.unfold(true);
holder.binding.reviewBody2.setText(review.getComment());
holder.binding.reviewAuthor2.setText(review.getUsername());
return;
}
holder.binding.foldingCell.fold(true);
holder.binding.reviewAuthor.setText(review.getUsername());
if (review.isHasSpoiler()) {
holder.binding.reviewBody.setVisibility(View.GONE);
holder.binding.reviewSpoiler.setVisibility(View.VISIBLE);
} else {
holder.binding.reviewBody.setText(review.getComment());
holder.binding.reviewBody.setVisibility(View.VISIBLE);
holder.binding.reviewSpoiler.setVisibility(View.GONE);
}
holder.binding.reviewTime.setText(review.getCreatedAt());
}
// ViewHolder
public class ReviewViewHolder extends RecyclerView.ViewHolder {
ItemListReviewBinding binding;
public ReviewViewHolder(final ViewGroup itemView) {
super(itemView);
binding = DataBindingUtil.bind(itemView);
binding.reviewItem.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// onReviewClickListener.onReviewClicked(getAdapterPosition());
Log.e("TEST", "CLIKC");
if (foldingCellPosition != -1) {
currentFoldingCell.fold(false);
}
currentFoldingCell = binding.foldingCell;
binding.reviewBody2.setText(reviewList.get(getAdapterPosition()).getComment());
binding.reviewAuthor2.setText(reviewList.get(getAdapterPosition()).getUsername());
binding.foldingCell.toggle(false);
foldingCellPosition = getAdapterPosition();
}
});
binding.reviewItem2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
binding.reviewItem2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
foldingCellPosition = -1;
binding.foldingCell.fold(false);
}
});
}
});
}
}
}
How the recycler view is created:
layoutManager = new LinearLayoutManager(getContext());
mBinding.movieDetailReviewListRvReviews.setHasFixedSize(true);
mBinding.movieDetailReviewListRvReviews.setLayoutManager(layoutManager);
mBinding.movieDetailReviewListRvReviews.setAdapter(adapter);
What I tried so far
I really dont have any idea why this happens.
However I tried notifyDataSetChanged() after each collapse/expand as well as invalidate().
Edit
For the collapsing / expanding effect I use this library:https://github.com/Juriv/folding-cell-android
Actually there were a lot of problems with my code. First of all, as rom4ek mentioned, I had to change foldingCellPosition = getAdapterPosition() to foldingCellPosition = getLayoutPosition(). The next Problem, was this call:
if(foldingCellPosition != -1) {
currentFoldingCell.fold(false);
}
Not visible views should fold, which resulted in strange behaviour, so I added this code:
public void checkForHide(int first, int last){
if(foldingCellPosition != -1){
if(foldingCellPosition < first || foldingCellPosition > last){
foldingCellPosition = -1;
}
}
}
If the unfolded view is not visible the folding cellposition will set to -1 instead of folding it manually.
It is called from the Fragment here:
mBinding.movieDetailReviewListRvReviews.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
// Load more data if reached the end of the list
adapter.checkForHide(layoutManager.findFirstVisibleItemPosition(), layoutManager.findLastVisibleItemPosition());
if (layoutManager.findLastVisibleItemPosition() == adapter.reviewList.size() - 1 && !isLoadingLocked && !isLoading) {
if (pageToDownload < totalPages) {
mBinding.layoutContent.pbLoadingMore.setVisibility(View.VISIBLE);
downloadMovieReviews();
}
}
}
});
Try leaving cardview:cardUseCompatPadding false, which is the default.
From https://developer.android.com/reference/android/support/v7/widget/CardView.html#setUseCompatPadding(boolean)
setUseCompatPadding
added in version 24.2.0 void setUseCompatPadding (boolean
useCompatPadding) CardView adds additional padding to draw shadows on
platforms before Lollipop.
This may cause Cards to have different sizes between Lollipop and
before Lollipop. If you need to align CardView with other Views, you
may need api version specific dimension resources to account for the
changes. As an alternative, you can set this flag to true and CardView
will add the same padding values on platforms Lollipop and after.
Since setting this flag to true adds unnecessary gaps in the UI,
default value is false.
This implies that the CardView may be adding padding when you collapse/expand cards.

Categories