CardAdapter jumps automatically when a request is sent to load image - java

I'm trying to implement an IM-like application, but I get stuck on problem which really annoys me.
I use recyclerview to show messages in a scrolling manner, so that users can scroll the views to see all of the messages. Messages' base layout is a cardview
widget.
Additionally, I've use another layout within the Messages' layout which is also a cardview to show sub-messages.
To be more detailed, I would like to visualize the layouts which I used. Look at the following picture:
As you see I use two nested cardviews (inside each other). Moreover, as I use recyclerview for sub-messages, I have scrolling behavior. When I scroll sub-messages, the onBindViewHolder method of recyclerview is called. To retrieve each image, I call an API in onBindViewHolder method.
Now the problem arises when I want scroll the sub-messages. It seems that when the API is called something goes wrong. Although the image is retrieved successfully from API, it jumps down and up screen.
For example, If I scroll last message's sub-messages to the right. It ends up with the following result:
This is the onBindViewHolder() method of sub messages adapted, for working with the images, I use Glide android library:
public class SubMenuAdapter extends RecyclerView.Adapter<SubMenuAdapter.ViewHolder> {
.
.
.
public void onBindViewHolder(ViewHolder holder, int position) {
SubMessage subMessage = subMessageList.get(position);
final long mediaFileId = subMessage.getMediaFileId();
holder.ivSubmessageImage.setImageDrawable(null);
if (mediaFileId != 0) {
holder.ivSubmessageImage.setImageResource(R.mipmap.ic_launcher);
holder.ivSubmessageImage.setMinimumHeight(100);
holder.ivSubmessageImage.setMinimumWidth(200);
Glide.with(context).load(Config.FILE_SERVER_URL+"api/file/" + mediaFileId + "/thumb")
.into(holder.ivSubmessageImage);
holder.ivSubmessageImage.setVisibility(View.VISIBLE);
} else {
holder.ivSubmessageImage.setImageBitmap(null);
holder.ivSubmessageImage.setVisibility(View.INVISIBLE);
}
...
}
.
.
.
}
This is the layouts which I've created (at the moment):
channel_log_list.xml (msgCardview)
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
app:cardCornerRadius="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="#style/MyCardViewStyle"
android:layout_marginTop="3dp"
android:padding="2dp"
android:layout_marginBottom="1dp"
android:foreground="?android:attr/selectableItemBackground"
android:clickable="true"
android:layout_marginRight="23dp"
app:cardPreventCornerOverlap="false"
android:layout_marginLeft="23dp"
app:cardBackgroundColor="#color/chatMsgBg"
android:id="#+id/channelLogCard"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:layout_width="45dp"
android:layout_height="45dp"
android:id="#+id/ivMessageImage"/>
<com.example.TextViewPlus
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:text="messages"
app:customFont="#string/irs"
android:id="#+id/channelLogAppletTitle"
android:textSize="#dimen/content_text_size_small2"
android:layout_marginBottom="10dp"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/lstSubMessages"
android:layout_width="wrap_content"
android:layout_height="match_parent"/>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
sub_message_list_item.xml (subMsgCardview)
<?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="200dp"
app:cardCornerRadius="3dp"
android:layout_height="300dp"
style="#style/SubMessageCardViewStyle"
android:id="#+id/SubMessageCard">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layoutDirection="rtl">
<ImageView
android:layout_width="match_parent"
android:layout_height="110dp"
android:id="#+id/ivSubMessageImage"
android:visibility="invisible"/>
<com.example.TextViewPlus
android:padding="5dp"
android:layout_marginTop="10dp"
android:id="#+id/tvText"
app:customFont="#string/irs"
android:textSize="#dimen/content_text_size_small1"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</android.support.v7.widget.CardView>

make your Cardview android:focusableInTouchMode="true" or make that layout which you want to focus

Related

Centre text inside a Cardview - Android Studio

I'm currently using a Card View inside a recycler and the text is left-alligned despite my efforts.
Here is the Book Item Layout.
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="match_parent"
app:cardCornerRadius="4dp"
app:cardElevation="5dp"
app:cardUseCompatPadding="true"
app:cardBackgroundColor="#color/white">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<TextView
android:id="#+id/bookTitleTextView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_gravity="center_horizontal"
/>
</LinearLayout>
</androidx.cardview.widget.CardView>
Here is the recycler itself.
<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/bookRecycler" />
This is the current output.
enter image description here
As you can see the text is not centered.
I tried using layout gravity to center the text which didn't work.
I also tried using a constraint layout on the text view and using constraints to center the text without any luck.
android:layout_gravity = "center" has already been attempted.
Any advice on what I'm overlooking would be great.
Thank you.
add android:gravity="center" for LinearLayout and you are good to go
I see your LinearLayout have only one child and no special attributes, so you can even remove whole LinearLayout - place TextView straight inside CardView, which extends FrameLayout. For centering childs inside FrameLayout you may also use android:gravity="center" for parent and/or android:layout_gravity="center" for child
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:gravity="center"
app:cardCornerRadius="4dp"
app:cardElevation="5dp"
app:cardUseCompatPadding="true"
app:cardBackgroundColor="#color/white">
<TextView
android:layout_gravity="center"
... rest of code
android:gravity="center" is the correct code, instead of android:layout_gravity="center_horizontal"

What is the right way to use two scrollviews in a single activity?

This is my current design in my main activity.
<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">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/txtSubestacion"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="Subestacion"
android:textSize="18sp" />
<Spinner
android:id="#+id/spSubestacion"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:spinnerMode="dropdown" />
<TextView
android:id="#+id/txtClasificacion"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="Clasificacion"
android:textSize="18sp" />
<Spinner
android:id="#+id/spClasificacion"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:spinnerMode="dropdown" />
<ScrollView
android:id="#+id/scrollEventos"
android:layout_width="match_parent"
android:layout_height="350dp"
android:paddingTop="30dp"
android:paddingBottom="10dp">
<LinearLayout
android:id="#+id/linearEventos"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
</ScrollView>
<Button
android:id="#+id/btnRegistros"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Actualizar Registros" />
</LinearLayout>
</ScrollView>
I have a second scrollview inside the first one because this one is filled with multiple labels created from code. These labels can take up a lot of space, so a scrollview is suitable for proper navigation.
The first scrollview that contains everything is so that when changing the screen in landscape mode, you can continue browsing and access all the controls that are displayed.
The problem is that when changing the screen in landscape mode, only the first scrollview works, which allows you to see all the controls correctly. However, the second scrollview showing the records cannot be moved, and therefore the records are cut.
Is there a way to freeze the first scrollview when the user wants to slide the records and allow the second scrollview to be moved?
Or is it that I should create my design differently?
Note: Everything works correctly with the screen in portrait mode. All the controls are accessible at first instance and the second scrollview can be slid correctly allowing to see the records.
I've tried working with the layout_weight property but it didn't work for me or I just didn't know how to use it.
Use this:
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<!-- Other Layout or scrollView-->
</android.support.v4.widget.NestedScrollView>
Android site: NestedScroll

Android LinearLayout, set background to Transparent

I am inflating a bottom_sheet_layout. It contains a LinearLayout as the root element. It has one child CardView.
I've tried the following:
setting `android:background` property to
1. #00FFFFFF
2. #00000000
3. #android:color/transparent
setting the background color of LinearLayout programatically
`LinearLayout l = container.findViewById(R.id.root_element);
l.setBackgroundColor(Color.TRANSPARENT);`
This is the BottomSheet.Class that is linked to the bottom_sheet_layout
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.bottom_sheet_layout, container, false);
LinearLayout l = container.findViewById(R.id.root_element);
l.setBackgroundColor(Color.TRANSPARENT);
return v;
}
This is the full bottom_sheet_layout
<?xml version="1.0" encoding="utf-8" ?>
<LinearLayout
android:id="#+id/root_element"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_margin="16dp">
<!-- A CardView that contains a TextView -->
<androidx.cardview.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
card_view:cardCornerRadius="4dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/poiName"
android:fontFamily="#font/comfortaa_bold"
android:text="#string/poiName"
android:textSize="20sp"
android:layout_marginTop="20dp"
android:layout_marginLeft="20dp"
android:layout_marginBottom="20dp"/>
<!--Location-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="10dp"
android:fontFamily="#font/work_sans_medium"
android:text="#string/ui_location"
android:textFontWeight="800" />
<TextView
android:id="#+id/location"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="10dp"
android:fontFamily="#font/work_sans"
android:text="#string/ui_location_addr" />
</LinearLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_marginTop="10dp"
android:layout_marginBottom="20dp"
android:layout_marginRight="20dp"
android:src="#drawable/share"
android:scaleType="center"
card_view:backgroundTint="#color/colorPrimary" />
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
This is the Map Fragment. Here is where I inflate the bottom_sheet_layout
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MapsActivity" />
Following several guides, I still could not get the #00FFFFFF method to work. Programmatically setting the color to transparent, crashes the application.
It seems that in earlier questions on StackOverflow, setting the background to the hex code with alpha value used to work. Now I only get a dim gray background.
Screenshots of the application
Image Layout
App ScreenShot
If you are not using MapView, I supposed that you are inflating the Google Map + bottom_sheet_layout in the same fragment. If Yes, I think that your issue is not the LinearLayout transparency but you are inserting bottom_sheet_layout to the bottom of the fragment container, not over the map.
You can use this layout for your Map fragment
(androidx, but very similar if you are using android)
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- use this fragment for your google map -->
<fragment
android:id="#+id/google_map"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<!-- use this fragment for your bottom_sheet class -->
<fragment
android:id="#+id/bottom_sheet"
android:layout_margin="16dp" // with this you do not need the LinearLayout root_element
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Then, you can play with your CardView (or LinearLayout) visibility to show the card or not.
Other layouts are possible like using directly the card view instead of a Fragment.
I think I can help you with some sort of solutions, which you can also try and see if that works or not.
Make use of alpha property in your .java file
Range the value as per your ease
LinearLayout l = container.findViewById(R.id.root_element);
l.setAlpha(0.4);
You can make use of alpha in your XML file too:
<LinearLayout
android:id="#+id/l1"
android:alpha="0.5"
android:layout_width="190dp"
android:layout_height="match_parent">
0.0 is for fully transparent and 1.0 is for fully opaque.
Let me know if any of the solutions work for you. However, do more research here, you will definitely get a solution. Happy coding.
Try background null.
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="#null">
......
</LinearLayout>
Are you sure that the child layout elements doesn't have backgrounds?

How can i remove unnecessary top padding in cardview?

I managed to implement Cardviews in my app, but the cardview show an unnecessary padding in the top.
What i want to achieve is to get a header image like this :
Here's my cardview Layout file :
<android.support.v7.widget.CardView
android:id="#+id/programCardview"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="match_parent"
card_view:cardUseCompatPadding="true"
xmlns:card_view="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="#+id/programHeader"
android:layout_width="match_parent"
android:layout_height="160dp"
android:src="#drawable/createdprogramviewcard"/>
<RelativeLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:paddingBottom="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp">
<TextView
android:id="#+id/programTitle"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="Programme d'endurance"
android:textSize="20sp"
android:textAlignment="center"/>
<TextView
android:id="#+id/objectif"
android:layout_below="#+id/programTitle"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="Objectif : " />
<TextView
android:id="#+id/programObjectif"
android:layout_below="#+id/programTitle"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="6 séances"
android:layout_toRightOf="#id/objectif"/>
<TextView
android:id="#+id/programWorkouts"
android:layout_below="#+id/programTitle"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:textAlignment="textEnd"
android:layout_alignParentRight="true"
android:text="6 séances" />
</RelativeLayout>
</LinearLayout>
This is the code of the RecyclerView :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerViewPrograms"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
I manage to change the attribute cardUseCompatPadding but that not affect the internal form of the cardview, it's just there to separate them.
Thanks in advance.
I found a solution for my problem by changing the height of the imageView to 130dp. Apparently since i made the with of the image to match_parent, i had to find the exact height that will suit the image inside the cardview without giving it some extra padding.
The situation is due to two reasons, the first is that the height property of the CardView is in match_parent or in a larger size than the components occupy and at the same time the gravity property of the layout is in center.
To fix it just set the gravity of the LinearLayout to center | fill or just to fill.
I used these below attributes and it works for me.
card_view:cardElevation="0dp"
card_view:cardMaxElevation="0dp"
Or you can just use MaterialCardView instead of legacy CardView

How to center Textview inside Listview using RelativeLayout?

ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this,R.layout.activity_haltestellen, R.id.tvHaltestellen, HaltestellenListe);
lvH.setAdapter(arrayAdapter);
this is how the stuff is set and .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" >
<ListView
android:id="#+id/lvHaltestellen"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" >
</ListView>
<TextView
android:id="#+id/tvHaltestellen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
/>
I get the StringArray from a database.
so how can center the tv inside the listview? realy bad thing
Try to add this one: android:layout_centerInParent="true"
<TextView
android:id="#+id/tvHaltestellen"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
I'm not quite sure what do you want to do, but if you want to center the TextView inside the RelativeLayout then remove
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
from TV and try adding something like android:layout_centarInParent="true", and in the relative layout change match_parent to wrap_contents
You could anchor the TextView to the top and bottom of the ListView (and optionally left and right too, depending on the desired effect). That will make the TextView equally tall (and optionally wide), so use a center gravity to position the text in the middle.
<?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" >
<ListView
android:id="#+id/lvHaltestellen"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" />
<TextView
android:id="#+id/tvHaltestellen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/lvHaltestellen"
android:layout_alignBottom="#+id/lvHaltestellen"
android:layout_alignLeft="#+id/lvHaltestellen"
android:layout_alignRight="#+id/lvHaltestellen"
android:gravity="center" />
</RelativeLayout>
If you're planning to add a background colour to the TextView, you'll need to wrap it inside another transparent container (e.g. a FrameLayout), to avoid the colour from obscuring what's displayed in the list. Something like:
<?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" >
<ListView
android:id="#+id/lvHaltestellen"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" />
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/lvHaltestellen"
android:layout_alignLeft="#+id/lvHaltestellen"
android:layout_alignRight="#+id/lvHaltestellen"
android:layout_alignTop="#+id/lvHaltestellen" >
<TextView
android:id="#+id/tvHaltestellen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="#android:color/black" />
</FrameLayout>
</RelativeLayout>
Alternatively, if you decide to make the ListView fill up the whole height of the RelativeLayout, you don't need to anchor the TextView to the list anymore. As already pointed out by #user1796624, you can then just center the TextView.
As per your earlier comment on someone else's answer:
the textview is shown inside the listview.
I understand what you're trying to say here, but please do realize that the TextView does not sit inside the ListView, but rather floats on top of it.

Categories