Background Image when RecyclerView is empty - android

Do you know how to set a background image when the recycler view is empty? Like Gmail app...
Question 2: is there a repository where I can find official images by Google for this purpose?
EXAMPLE

Yes, there is an official, Google maintained Github repository. Contains the latest version of their material icons, which are used on all Google apps.
Google's Material Design Icons Repository
And, regarding your first question: yes.
You can check if the adapter you are using to populate your RecyclerView is empty (or/and if the adapter has no items). If true, show the image, else, deal with the RecyclerView. Like this:
if (mAdapter.getItemCount() == 0) {
// show my background image
// do stuff
} else {
// RecyclerView stuff
}

To elaborate a bit on #herrmartell answer and to manage streched drawables as background: This solution switches the howl recView for another linearlayout having the same effect as you request but looks in my case prettier after trying lots of different possibilities. If you change your list you have to call the handler function abviously again.
Your Fragment that handles the RecyclerView:
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
//...
//setup recView like -> recView = view.findViewById(R.id.yourListRecyclerView);
//adapter setup
//set to recView
handleRecyclerViewState(view);
}
private void handleRecyclerViewState(View view) {
View emptyView = view.findViewById(R.id.empty_view);
if (adapter.getItemCount() == 0) {
recView.setVisibility(View.GONE);
emptyView.setVisibility(View.VISIBLE);
} else {
recView.setVisibility(View.VISIBLE);
emptyView.setVisibility(View.GONE);
}
}
Inside your RecView layout xml:
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/yourListRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:paddingBottom="80dp"
android:scaleType="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.503"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0" />
<include
android:id="#+id/empty_view"
android:layout_gravity="center_horizontal|bottom"
layout="#layout/empty_view"
android:layout_height="match_parent"
android:layout_width="match_parent">
</include>
Exact layouting and design might differ for sure.
Here the Layout of the empty_view.xml that shows a drawable svg image and a message underneath:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone"
tools:visibility="visible">
<ImageView
android:id="#+id/empty_image"
android:layout_width="220dp"
android:layout_height="250dp"
android:src="#drawable/ic_no_files" />
<TextView
android:id="#+id/emptyMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Nothing here!"
android:alpha="0.3"
android:textColor="?android:attr/textColor" />

Related

Xamarin Android LinearLayout - Problem with 2 RecyclerViews on one page

I'm having issues with the v7.widget.RecyclerView. I have a "post" from the app user, which displays any images they have previously added, as well as any other attachments (documents, videos etc.). There is an option to edit existing posts.
I have an EditPost xml file which embeds a file called attachment_item. This in turn embeds an xml file called EditAttachmentsLayout. I can post code from the first 2 files if needed, but I don't think the problem is in there.
The EditAttachmentsLayout page uses 2 RecyclerViews; one for images, and another for other files. Code is here:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.RecyclerView
android:id="#+id/edit_images_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<android.support.v7.widget.RecyclerView
android:id="#+id/edit_attachments_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
The problem is that when the Attachments recyler has items to display, it places some sort of overlay over the first (and only the first) image, like so:
If I hit the Cross button over the thumbnail (or the cross button on the attachment itself), the attachment is removed and the image then appears, as such:
It's as if the recycler is placing an overlay of some sort over the first image in the list. I have tried all sorts of things to address it, such as adding spacing to try to force the two recyclers apart, and switching to a GridView, as below:
<?xml version="1.0" encoding="utf-8"?>
<GridLayout 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:rowCount="4">
<android.support.v7.widget.RecyclerView android:id="#+id/edit_images_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_row="0"
android:scrollbars="none"/>
<Space
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_row="1"
android:layout_marginBottom="10dp"/>
<android.support.v7.widget.RecyclerView android:id="#+id/edit_attachments_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_row="2"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
android:scrollbars="none"/>
</GridLayout>
Unfortunately, the issue persists. The image is always covered, until I remove the attachment.
Any ideas...? I am stumped with this one.
EDIT:
Here is the code which sets up the recycler views:
private void SetupRecycler()
{
RecyclerView imagesRecyclerView = FindViewById<RecyclerView>(Resource.Id.edit_images_recycler);
RecyclerView attachmentsRecyclerView = FindViewById<RecyclerView>(Resource.Id.edit_attachments_recycler);
LinearLayoutManager imagesLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.Horizontal, false);
LinearLayoutManager attachmentsLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.Vertical, false);
imagesRecyclerView.SetLayoutManager(imagesLayoutManager);
attachmentsRecyclerView.SetLayoutManager(attachmentsLayoutManager);
IList<DeviceFile> localFiles = _fileUtil.GetLocalFiles(_postEntry.MobileId);
_editImageAdapter = new EditImageAdapter(_postEntry, localFiles.Where(file => file.IsThumbnail).ToList());
_editAttachmentAdapter = new EditAttachmentAdapter(_postEntry, localFiles.Where(file => !file.IsThumbnail).ToList());
imagesRecyclerView.SetAdapter(_editImageAdapter);
attachmentsRecyclerView.SetAdapter(_editAttachmentAdapter);
_editImageAdapter.LocalFileDeleted += LocalFileDeleted;
_editImageAdapter.UploadedFileDeleted += UploadedFileDeleted;
_editAttachmentAdapter.LocalAttachmentDeleted += LocalFileDeleted;
_editAttachmentAdapter.UploadedAttachmentDeleted += UploadedFileDeleted;
}
EDIT 2:
So here is the overlay which adds a removal button to the image when the post is in edit mode. Apologies for not including it earlier, I didn't build this app so don't know everything about it:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_marginRight="20dp"
android:layout_width="#dimen/edit_image_size"
android:layout_height="#dimen/edit_image_size">
<ImageView
android:background="#drawable/image_background"
android:id="#+id/attachment_image"
android:scaleType="fitXY"
android:layout_width="#dimen/edit_image_size"
android:layout_height="#dimen/edit_image_size"/>
<ImageButton
android:background="#drawable/rounded_button_secondary"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:layout_alignTop="#id/attachment_image"
android:layout_alignRight="#id/attachment_image"
android:id="#+id/delete_attachment_button"
android:src="#drawable/icon_of_cross"
android:tint="#color/white"
android:padding="5dp"
android:layout_margin="5dp"
android:layout_width="25dp"
android:layout_height="25dp" />
Just for a bit of clarity, I have included some more screenshots, with multiple images and attachments. If there are both images and attachments in the post, the first image to be loaded (the one firthest right) will have the overlay:
Once I click the cross button to remove the first attachment, the attachment is gone (as expected) and the image is visible again:
Very strange!
Suggestions:
1. Try to set parent linear layout height to match_parent
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"> // **this line here**
<android.support.v7.widget.RecyclerView
android:id="#+id/edit_images_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<android.support.v7.widget.RecyclerView
android:id="#+id/edit_attachments_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Have you tried to see if you are having an issues with the main thread
RunOnUIThread(() => {}) - to update the adapters
Try notifying the recycler adapters for the changes by using:
_editImageAdapter.NotifiyDatasetChanged()
_editImageAdapter.NotifiyDatasetChanged()

How to hide Particular view in RecyclerView?

I have to hide Particular views in recyclerview, I am trying to hide some views but view has gone but space is there,I have tried putting heights=0 in cardview but still did not work , what I should I do?
This is my XML code list data
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-
auto">
<android.support.v7.widget.CardView
android:id="#+id/child_card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="2sp"
app:cardElevation="12sp"
android:visibility="gone">
<LinearLayout
android:id="#+id/main_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="?attr/selectableItemBackground"
android:gravity="center"
android:orientation="vertical"
android:padding="3dp"
android:visibility="visible">
<ImageView
android:id="#+id/icon"
android:layout_width="48dp"
android:layout_height="48dp"
app:srcCompat="#drawable/bsp_icon" />
<android.support.v7.widget.AppCompatTextView
android:id="#+id/label_value"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:lines="2"
android:maxLines="2"
android:padding="0dp"
android:textColor="#color/Black" />
</LinearLayout>
</android.support.v7.widget.CardView>
</layout>
and this is my recyclerview
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="0dp"
tools:listitem="#layout/list_layout_dashboard_child_view">
</android.support.v7.widget.RecyclerView>
this is my Adapter code
if (txnTypeMap.get("CUST_CR") != null &&
obj.getChildName().equalsIgnoreCase(txnTypeMap.get("CUST_CR"))) {
binding.childCardView.setVisibility(View.VISIBLE);
}
important always set this if you are sure your data will change in recyclerview mRecyclerView.setHasFixedSize(false);
first remove the item from list e.g. list.remove(position which you want to hide)
next call notifyItemChanged(postion) and it should work ->this is better approach than calling notifyDataSetChanged()
You should hide all views or parent from UsersViewholder layout xml. You should hide entire viewholder or each view
Entire viewholder:
itemView.setVisibility(View.GONE);
or each element:
view.setVisibility(View.GONE);
But don't forget to set them VISIBLE otherwise, you will end up with some strange things from recycling
Without setting setVisibility to View.GONE, try to remove the the data from the data source and call notifyDataSetChanged()
This is the more efficient way to hide a view from RecyclerView
you have to set visibility gone to view in else case because views are reused in recycler view
if (txnTypeMap.get("CUST_CR") != null &&
obj.getChildName().equalsIgnoreCase(txnTypeMap.get("CUST_CR"))) {
binding.childCardView.setVisibility(View.VISIBLE);
} else binding.childCardView.setVisibility(View.GONE);
I hope it will work.

RecyclerView Scrollbar is not visible in Dialog Fragment in Android

I have a dialog fragment, in which I have a recycler view. I want to add a scrollbar to the recycler view. I added scrollbars="vertical" but it's not showing up. I think the issue has something to do with the themes.
Here is my xml:
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:padding="16dp"
tools:context="com.airxos.app.common.fragments.LayerSwitcherFragment">
<TextView
android:id="#+id/layer_list_title"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:fontFamily="sans-serif"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="#color/black_87"
android:text="#string/layers"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/layer_list"
android:layout_marginTop="#dimen/margin_16"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/layer_list_title"
app:layout_constraintEnd_toEndOf="parent"
android:layout_height="0dp"
android:maxHeight="#dimen/info_window_height"
android:layout_width="match_parent"
android:nestedScrollingEnabled="true"
android:scrollbars="vertical"
android:background="#color/white"
android:scrollbarThumbVertical="#drawable/scrollbar"
android:scrollbarSize="5dp"
android:padding="5dp"
android:scrollbarStyle="insideInset"/>
</android.support.constraint.ConstraintLayout>
I am restricting the height and width of the dialog fragment as shown below:
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
Objects.requireNonNull(inflater, "LayoutInflater");
if(getDialog().getWindow() != null) {
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
getDialog().setCanceledOnTouchOutside(true);
}
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_layer_switcher, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
Objects.requireNonNull(view, "View");
super.onViewCreated(view, savedInstanceState);
layerList = view.findViewById(R.id.layer_list);
layerList.setAdapter(new LayerListAdapter(context, layers, layerSelectionListener));
layerList.setLayoutManager(new LinearLayoutManager(context));
}
I have already tried everything suggested in this SO question and it did not work.
Other than this I have also tried creating a drawable and adding it as scrollbarThumbVertical
I think it has something to do with the themes because even when I change the background color of constraint layout it is not showing up in the dialog.
EDIT:
I am showing the dialog as shown below:
LayerSwitcherFragment switcherFragment = LayerSwitcherFragment.newInstance(layers);
FragmentTransaction ft = getChildFragmentManager().beginTransaction();
Fragment prev = getChildFragmentManager().findFragmentByTag("layer_dialog");
if (prev != null) {
ft.remove(prev);
}
ft.addToBackStack(null);
switcherFragment.show(ft, "layer_dialog");
EDIT: Issue is solved.
I am sorry for wasting everyone's time. The issue was a stupid mistake we made. My DialogFragment was in a Library. We build the arr file and was using it inside the app. The issue was that we forgot to remove the dialogfragment's XML files from the main app when we refactored it to the arr library. So even after we update the files in the library, the app was picking up the old file in the main app instead of the updated file because the name of the XML was the same.
Try:
android:fadeScrollbars="false"
android:scrollbarAlwaysDrawVerticalTrack="true"
Try This:
In XML:
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:scrollbars="vertical" <!-- type of scrollbar -->
android:scrollbarThumbVertical="#android:color/darker_gray"
android:scrollbarSize="5dp"
android:layout_width="match_parent"
android:layout_height="match_parent" />
In your xml, Just set the android:scrollbars="vertical" it can work.
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"
app:layoutManager="android.support.v7.widget.LinearLayoutManager" />
I know this can come kind of late. Try to use a NestedScrollView as the parent of the RecyclerView. Like this:
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/layer_list_title"
app:layout_constraintEnd_toEndOf="parent"
android:scrollbars="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/layer_list"
android:layout_marginTop="#dimen/margin_16"
android:layout_height="wrap_content"
android:maxHeight="#dimen/info_window_height"
android:layout_width="match_parent"
android:nestedScrollingEnabled="true"
android:background="#color/white"
android:padding="5dp"/>
</androidx.core.widget.NestedScrollView>
I guess in DialogFragment you scrollbar is transparent
try this code
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/mTaskListRV"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbarSize="5dp"
android:scrollbarThumbVertical="#drawable/shape_progress"
android:scrollbarTrackVertical="#drawable/shape_round_gray"
android:scrollbars="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="#layout/cash_out_task_list_item_layout" />

Chat scroll(recycler view) not smooth because of variable size image loading?

I am trying to make a chat application. Where I have different layouts for receive messages and send messaged. I am not able to get smooth scroll maybe because of variable image size? I think this issue related to layout I have made for the chat message box.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
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" xmlns:tools="http://schemas.android.com/tools"
android:layout_marginTop="11dp"
android:layout_marginRight="16dp"
android:gravity="right"
>
<android.support.v7.widget.AppCompatTextView
android:id="#+id/tv_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="11dp"
android:paddingVertical="9dp"
android:visibility="gone"
tools:text="fdsfdsfsdfs"
tools:visibility="gone"
android:textColor="#2A2617"
android:textSize="15dp"
android:fontFamily="#font/nunito_regular"
/>
<android.support.v7.widget.AppCompatImageView
android:id="#+id/iv_message"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="#+id/tv_message"
android:layout_width="200dp"
android:layout_height="200dp"
android:scaleType="centerCrop"
android:padding="11dp"
android:visibility="gone" />
</RelativeLayout>
It flickers when i scroll up. Code of View Holder is as follow
when(data.messageType){
Constant.MessageType.TEXT ->{
messageIv.visibility = View.GONE
messageTv.apply {
visibility = View.VISIBLE
text = data.content
}
}
Constant.MessageType.IMAGE -> {
Glide.with(messageIv.context)
.load(data.content)
.apply(
RequestOptions()
.apply {
diskCacheStrategy(DiskCacheStrategy.ALL)
skipMemoryCache(true)
})
.into(messageIv)
messageIv.visibility = View.VISIBLE
messageTv.apply {
visibility = View.GONE
}
}
}
I guess it call bind every time i scroll and it makes the visibility gone and visible. Which cause the view to have 0dp size for some amount of time and suddenly when image loads, it creates a sudden scroll in the view making it very unstable.
Any work-around for this?

The Android Progress bar not showing up

This is my layout xml:
<RelativeLayout 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="match_parent"
android:background="#color/fragment_body"
android:fitsSystemWindows="true">
<include
android:id="#+id/contextToolBar"
layout="#layout/context_toolbar_layout" />
<android.support.v7.widget.RecyclerView
android:id="#+id/list1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/contextToolBar"
android:scrollbarSize="5dp"
android:scrollbarThumbVertical="#color/scrollbarColor"
android:scrollbars="vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<ProgressBar
android:id="#+id/delete_progress"
style="#style/Widget.AppCompat.ProgressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:visibility="gone" />
It displays a grid of images in the recyclerview.
I can select a bunch of images & have an option to delete them.
The following is the delete logic:
public void deleteSelectedFiles(final Context context, final List<MediaModel> selectionList) {
String confirmationMessage = getString(R.string.delete_confirm_message);
new AlertDialog.Builder(context)
.setTitle(getString(R.string.action_delete))
.setMessage(confirmationMessage)
.setIcon(android.R.drawable.ic_dialog_alert)
.setPositiveButton(android.R.string.yes, (dialog, whichButton) -> {
View progressBar = getActivity().findViewById(R.id.delete_progress);
dialog.cancel();
progressBar.setVisibility(View.VISIBLE);
deleteFileList(selectionList, this.getActivity());
progressBar.setVisibility(View.GONE);
})
.setNegativeButton(android.R.string.no, null).show();
}
I am expecting the progress bar to display in the foreground while the delete operation is going on. But it just doesn't show up. Any help would be highly appreciated.
So I had this problem before. In my case it was because I was using a Material Design Theme for the whole app, so I had to use a specific orientation and it solved my problem. You can try with
<ProgressBar
android:id="#+id/progressBarReady"
style="#android:style/Widget.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="3dp"
android:indeterminate="true"
android:visibility="visible"/>
I had a similar problem. In my case, I was using a ProgressBar as a loading indicator inside a CoordinatorLayout.
In the Activity/Fragment - at different points - based on the data becoming available - ie using a Cursor or from the Network, I needed to call
mViewA.setVisibility(View.GONE)
or mViewB.setVisibility(View.VISIBLE).
When I set these up correctly for my views including the ProgressBar View, it became visible.
<ProgressBar
android:id="#+id/progressBar"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
style="?android:attr/progressBarStyle" is what fixed it for me.

Categories

Resources