Hide Views if Recyclerview is Empty - android

I have a RecyclerView with other widgets in this type of layout:
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="in.joey.joseph.aapnidukan.activities.CheckOutActivity">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/colorPrimary"
android:minHeight="?attr/actionBarSize">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/backIV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="#drawable/back_image"
android:padding="16dp"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="CheckOut"
android:textSize="18sp"
android:fontFamily="casual"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:gravity="center"
android:textColor="#android:color/white"/>
</RelativeLayout>
</android.support.v7.widget.Toolbar>
<RelativeLayout
android:id="#+id/nonEmptyState"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/toolbar"
android:visibility="visible">
<in.joey.joseph.aapnidukan.utils.EmptyRecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/checkOutRV"
/>
<RelativeLayout
android:id="#+id/cartTotalLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/checkOutRV"
android:layout_alignParentRight="true"
android:gravity="right"
android:layout_marginRight="20dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="right"
android:layout_marginRight="20dp"
android:padding="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Total: "
android:textSize="18sp"
android:textColor="#android:color/black"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="₹"
android:textSize="18sp"
android:textColor="#android:color/black"
android:layout_marginLeft="10dp"/>
<TextView
android:id="#+id/totalPriceTV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="8999"
android:textSize="18sp"
android:textColor="#color/colorPrimary"
android:layout_marginLeft="5dp"/>
</LinearLayout>
</RelativeLayout>
<Button
android:id="#+id/billingBtn"
android:layout_width="match_parent"
android:layout_height="70dp"
android:background="#color/colorAccent"
android:text="Proceed to Billing and Address"
android:textColor="#android:color/white"
android:textAllCaps="false"
android:textSize="20sp"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
<TextView
android:id="#+id/emptyState"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Add Items to Cart Before CheckOut"
android:textSize="18sp"
android:fontFamily="casual"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:gravity="center"
android:textColor="#android:color/black"
android:visibility="visible"/>
I have created a custom RecyclerView to handle empty states but it works fine for only the RecyclerView. The other views like the button are still visible when the list is empty. I have tried to hide it in my custom RecyclerView class like this:
private void checkNotEmpty(){
if (nonEmptyView != null && getAdapter() != null){
boolean nonEmptyViewVisible = getAdapter().getItemCount() > 0;
nonEmptyView.setVisibility(nonEmptyViewVisible ? VISIBLE : GONE);
setVisibility(nonEmptyViewVisible ? GONE : VISIBLE);
}
}
Here's the full class code for the RecyclerView:
public class EmptyRecyclerView extends RecyclerView {
private View emptyView, nonEmptyView;
public EmptyRecyclerView(Context context) {
super(context);
}
public EmptyRecyclerView(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
}
public EmptyRecyclerView(Context context, #Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
private final AdapterDataObserver dataObserver = new AdapterDataObserver() {
#Override
public void onChanged() {
checkEmpty();
}
#Override
public void onItemRangeInserted(int positionStart, int itemCount) {
checkEmpty();
}
#Override
public void onItemRangeRemoved(int positionStart, int itemCount) {
checkEmpty();
}
};
private void checkEmpty() {
if (emptyView != null && getAdapter() != null){
boolean emptyViewVisible = getAdapter().getItemCount() == 0;
emptyView.setVisibility(emptyViewVisible ? VISIBLE : GONE);
setVisibility(emptyViewVisible ? GONE : VISIBLE);
}
}
private void checkNotEmpty(){
if (nonEmptyView != null && getAdapter() != null){
boolean nonEmptyViewVisible = getAdapter().getItemCount() > 0;
nonEmptyView.setVisibility(nonEmptyViewVisible ? VISIBLE : GONE);
setVisibility(nonEmptyViewVisible ? GONE : VISIBLE);
}
}
public void setButtonVisibility(Button button){ // to toggle the button visibility
if (getAdapter().getItemCount() > 0){
button.setVisibility(View.VISIBLE);
} else {
button.setVisibility(GONE);
}
}
#Override
public void setAdapter(Adapter adapter) {
Adapter oldAdapter = getAdapter();
if (oldAdapter != null){
oldAdapter.unregisterAdapterDataObserver(dataObserver);
}
super.setAdapter(adapter);
if (adapter != null){
adapter.registerAdapterDataObserver(dataObserver);
}
checkEmpty();
}
public void setEmptyView(View view){
this.emptyView = view;
checkEmpty();
}
public void setNonEmptyView(View view2){
this.nonEmptyView = view2;
checkNotEmpty();
}
}
And in my activity, I have tried this:
init();
checkOutRV.setEmptyView(emptyState);
checkOutRV.setNonEmptyView(nonEmptyState);
private void init() {
nonEmptyState = findViewById(R.id.nonEmptyState);
emptyState = findViewById(R.id.emptyState);
checkOutRV = findViewById(R.id.checkOutRV);
checkOutRV.setHasFixedSize(true);
checkOutRV.setLayoutManager(new LinearLayoutManager(this));
}
The list has no data right now as I have not made my API call yet, but still, the emptyStateTextView and the buttons are still visible. How do I fix this?

By default keep your layout INVISIBLE and show a layout that shows that the Recyclerview has no data or something, and then when you make your API calls and receive the data then hide the layout which show that the recyclerview in empty and set your data layout view to VISIBLE which you want to show.
UPDATED ANSWER
You need to register Data observer to listen to data changes from sync adapter.
mRecyclerViewAdapter.registerAdapterDataObserver(myObserver);
RecyclerView.AdapterDataObserver are a result of which notify methods you call. So for instance if you call notifyItemInserted() after you add an item to your adapter then onItemRangeInserted() will get called
A more detailed example
protected void setupRecyclerView() {
mAdapter = new MyAdapter(mItemList);
mAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
#Override
public void onChanged() {
super.onChanged();
checkAdapterIsEmpty();
}
});
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setAdapter(mAdapter);
checkAdapterIsEmpty();
}
Also don't forget to unregister the observer.

In the checkNonEmpty() method you have called getAdapter() which returns null as you have not used setAdapter() on recycler view .
Create an adapter for your recycler view and initialise it with an empty list , then setAdapter() on your view.
Then you can use these statements
checkOutRV.setEmptyView(emptyState);
checkOutRV.setNonEmptyView(nonEmptyState);
Hope it helps !!

Try this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout >
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
>
...
</android.support.v7.widget.Toolbar>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/toolbar"
android:visibility="visible">
<RelativeLayout
android:id="#+id/nonEmptyState"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Existing layout like recyclerview, button -->
</RelativeLayout>
<RelativeLayout
android:id="#+id/emptyStateLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/emptyState"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:fontFamily="casual"
android:gravity="center"
android:text="Add Items to Cart Before CheckOut"
android:textColor="#android:color/black"
android:textSize="18sp"
android:visibility="visible"/>
</RelativeLayout>
</RelativeLayout>
</RelativeLayout>
Just set emptyStateLayout VISIBLE when RecyclerView is empty, otherwise GONE

Related

Ripple Effect in Android Recycler View is not working

I'm trying to add a ripple effect for the entire row (like we see in listview) in my Recycler View when the row is clicked.
I have tried
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
But still, I couldn't get the desired behavior. Even I have tried
android:foreground="?android:attr/selectableItemBackground"
But still no improvement
My listrow.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:orientation="horizontal"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true">
<RadioButton
android:id="#+id/radioButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/heading"
android:text="Title"
android:textSize="20dp"
android:paddingTop="5dp"
android:textStyle="bold"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:layout_toLeftOf="#+id/subHeading"
android:id="#+id/size"
android:text="Sub Title"
android:paddingTop="3dp"
android:paddingLeft="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
And My layout with Recycler View
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="match_parent">
<androidx.recyclerview.widget.RecyclerView
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:paddingTop="#dimen/list_item_spacing_half"
android:paddingBottom="#dimen/list_item_spacing_half"
android:layout_alignParentTop="true"
tools:context=".ListFragment"
tools:listitem="#layout/listrow" />
<Button
android:id="#+id/Save"
android:layout_width="match_parent"
android:text="Save"
android:layout_below="#+id/list"
android:textAllCaps="false"
android:layout_height="wrap_content"/>
</RelativeLayout>
Here is my adapter source code
private class listAdapter extends RecyclerView.Adapter<ViewHolder> {
private final int mItemCount;
final ArrayList<String> mTitles;
final ArrayList<String> msTitles;
ArrayList<RadioButton> radioButtons=new ArrayList<>();
listAdapter(int itemCount, ArrayList<String> titles, ArrayList<String> sTitles) {
mItemCount = itemCount;
mtitles=titles;
msTitles=sTitles;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(parent.getContext()), parent);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.sTitle.setTag(position);
holder.radioButton.setTag(position);
holder.title.setTag(position);
holder.title.setText(mTitles.get(position));
holder.sTitle.setText(msTitles.get(position));
View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View v) {
ItemCheckChanged(v);
}
};
holder.radioButton.setOnClickListener(listener);
holder.sTitle.setOnClickListener(listener);
holder.title.setOnClickListener(listener);
if(radioButtons.size()==0){
holder.radioButton.setChecked(true);
selectedItem=0;
}
radioButtons.add(holder.radioButton);
}
#Override
public int getItemCount() {
return mItemCount;
}
void ItemCheckChanged(View v){
selectedItem=(int)v.getTag();
for(RadioButton radioButton:radioButtons){
radioButton.setChecked(false);
}
radioButtons.get(selectedItem).setChecked(true);
notifyDataSetChanged();
}
public int getSelectedIndex(){
return selectedItem;
}
}
NOTE: I'm using these all things in BottomSheetDialog may it be reason?
You should set background to views that have set a click listener.
If you want to set the listener to the whole row you need to call only:
holder.itemView.setOnclickListener() and remove rest of them.

Movie recyclerview above keyboard in Android

I have my custom BottomSheetDialogFragment.Inside this dialog I have custom edittext and recyclerview.My goal is to move reyclerview above a keyboard,when it' showing. Here is a my custom edittext code
public class WrappedEditText extends android.support.v7.widget.AppCompatEditText {
public WrappedEditText(Context context) {
super(context);
}
public WrappedEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
public WrappedEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Nullable
private View wrapper;
#Nullable
public View getWrapper() {
return wrapper;
}
#Override
public void getFocusedRect(Rect r) {
if (wrapper != null) {
wrapper.getFocusedRect(r);
return;
}
super.getFocusedRect(r);
}
#Override
public boolean getGlobalVisibleRect(Rect r, Point globalOffset) {
if (wrapper != null)
return wrapper.getGlobalVisibleRect(r, globalOffset);
return super.getGlobalVisibleRect(r, globalOffset);
}
public void setWrapper(#Nullable View wrapper) {
this.wrapper = wrapper;
}
I'm using this code like this
searchView.setWrapper(rootView);
searchView.setOnFocusChangeListener((view1, b) -> {
if(searchView.getWrapper()==null)
searchView.setWrapper(rootView);
});
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/root_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#drawable/slide_menu_background"
android:orientation="vertical">
<RelativeLayout
android:id="#+id/close_view"
android:layout_width="wrap_content"
android:layout_height="#dimen/dimen_p_30"
android:layout_centerHorizontal="true"
android:layout_gravity="center"
android:orientation="vertical">
<View
android:layout_width="#dimen/dimen_p_40"
android:layout_height="#dimen/dimen_p_4"
android:layout_alignParentTop="true"
android:layout_marginTop="#dimen/dimen_p_10"
android:background="#drawable/slide_menu_title_line" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/title_conainer"
android:layout_width="match_parent"
android:layout_height="#dimen/dimen_p_30"
android:layout_below="#+id/close_view">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/dimen_p_30"
android:fontFamily="#font/myriad_geo_medium"
android:text="#string/insert_gif"
android:textColor="#color/black"
android:textSize="#dimen/dimen_p_14" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/search_layout"
android:layout_width="match_parent"
android:layout_height="#dimen/dimen_p_38"
android:layout_below="#+id/title_conainer"
android:layout_marginLeft="#dimen/dimen_p_30"
android:layout_marginRight="#dimen/dimen_p_30"
android:background="#drawable/rounded_corners_white">
<ImageView
android:id="#+id/search_icon"
android:layout_width="#dimen/dimen_p_24"
android:layout_height="#dimen/dimen_p_24"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="#dimen/dimen_p_8"
android:background="#mipmap/search_icon" />
<app.singltone.giphy.WrappedEditText
android:id="#+id/search_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:layout_gravity="center"
android:layout_marginLeft="#dimen/dimen_p_35"
android:layout_marginRight="#dimen/dimen_p_10"
android:background="#null"
android:fontFamily="#font/myriad_geo_medium"
android:gravity="center_vertical"
android:hint="#string/find_gif"
android:imeOptions="actionSearch"
android:inputType="textNoSuggestions"
android:singleLine="true"
android:textColor="#color/black"
android:textColorHint="#59000000"
android:textSize="#dimen/dimen_p_14" />
</RelativeLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/search_layout"
>
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:saveEnabled="true" />
</android.support.v4.widget.NestedScrollView>
</RelativeLayout>
rootView is a main view in xml file.This code working perfect only first time,but when user closed keyboard and then opened it again ,this code does not working.
Is a any way to solve this problem? or is this a correct solution?
Thanks

Icons not showing in Image View

I am trying to show the items into Recycler View in Grid Layout Manager.
My list item xml file is
<?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="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.v7.widget.CardView
app:cardElevation="3dp"
app:cardUseCompatPadding="true"
app:cardCornerRadius="10dp"
android:layout_margin="10dp"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="#+id/cardView">
<LinearLayout
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:id="#+id/itemLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="#+id/iv_icon"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginBottom="3dp"
android:layout_marginLeft="1dp"
android:layout_marginRight="1dp"
android:layout_marginTop="10dp"
android:adjustViewBounds="true"
android:paddingBottom="5dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:scaleType="fitCenter"
android:src="#mipmap/health_2" />
<TextView
android:id="#+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:ellipsize="end"
android:ems="5"
android:gravity="center"
android:lines="2"
android:maxEms="5"
android:maxLines="2"
android:text="Health" />
</LinearLayout>
</android.support.v7.widget.CardView>
</RelativeLayout>
And my code snippet is :
MainActivity :
mLayoutManager = new GridLayoutManager(MainActivity.this, 3);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(mLayoutManager);
adapter = new MyAdapter (MainActivity.this,
arrayList);
recyclerView.setAdapter(adapter);
MyAdapter :
#Override
public void onBindViewHolder(ViewHolder holder, final int position) {
model = arraylist.get(position);
holder.itemIcon.setImageResource(model.getIconName());
}
I am setting the icon name to model for the list in this way :
model.setIconName(R.mipmap.health_2);
Model Class :
public class DashBoardModel {
String itemName;
int iconName;
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public int getIconName() {
return iconName;
}
public void setIconName(int iconName) {
this.iconName = iconName;
}
}
My question is after doing these things , i am getting the output list as shown in the image below which is not the expected icon to be seen, How to resolve this ?
you could use the glide library com.github.bumptech.glide:glide:+ to dynamically load the icons into the image view, like so:
//assuming the getIconName method return an int, i.e R.mipmap.whatever
Glide.with(mContext).load(model.getIconName()).into(holder.itemIcon);
I have this same issue. Although I don't know why setting the image from the adapter doesn't work, I resolved it by posting a callback on ImageView's Handler.
#Override
fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
holder.itemIcon.post {
holder.itemIcon.setImageResource(...)
}
}

RecyclerView grid layout manager doesn't center items

I inherited some big project with a lot of legacy code and now I'm facing some weird stuff..
I need to make this screen have recyclerview with grid layout manager, 2 columns. This is what I get. Is there a way to center those icons in the middle of the screen? I tried with gravity, but nothing works. Maybe there is some thing inside all that legacy code that is making problem or this is just recyclerView's issue?
This is the item's layout (terrible, don't ask..)
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/color_view_controller_item_background"
android:orientation="vertical">
<TextView
android:id="#+id/textViewSceneKK"
android:layout_width="match_parent"
android:layout_height="#dimen/room_button_height"
android:layout_gravity="center"
android:layout_marginLeft="#dimen/row_filter_text_margin_left"
android:layout_marginRight="#dimen/row_filter_text_margin_left"
android:gravity="center"
android:shadowDx="-1"
android:shadowDy="-1"
android:shadowRadius="1"
android:textSize="#dimen/row_scene_kk_text_size" />
<TextView
android:id="#+id/textViewSceneName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="#dimen/row_filter_text_margin_bottom"
android:layout_marginLeft="#dimen/row_filter_text_margin_left"
android:layout_marginRight="#dimen/row_filter_text_margin_left"
android:layout_marginTop="#dimen/row_filter_text_margin_top"
android:clickable="false"
android:gravity="center"
android:longClickable="false"
android:textColor="#color/main_text_color"
android:textSize="#dimen/row_browser_right_name_text_size" />
</LinearLayout>
<!--<View-->
<!--android:id="#+id/filterView"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="match_parent"-->
<!--android:clickable="false"-->
<!--android:longClickable="false" />-->
<View
android:id="#+id/filterViewClick"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:selectableItemBackground"
android:focusable="false"
android:focusableInTouchMode="false" />
And fragment't layout:
<customview.CustomRecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none" />
And the code:
customRecyclerView.setHasFixedSize(false);
customRecyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2));
customRecyclerView.addItemDecoration(new DividerItemDecoration(getContext(),
R.drawable.line_separator_empty, DividerItemDecoration.VERTICAL_LIST));
customRecyclerView.setAdapter(adapter);
CustomRecyclerView.java
public class CustomRecyclerView extends RecyclerView {
private boolean enableScroll = true;
public CustomRecyclerView(Context context) {
super(context);
}
public CustomRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public boolean isEnableScroll() {
return enableScroll;
}
public void setEnableScroll(boolean enableScroll) {
this.enableScroll = enableScroll;
}
#Override
public int computeVerticalScrollRange() {
return super.computeVerticalScrollRange();
}
#Override
public boolean onInterceptTouchEvent(MotionEvent e) {
if (enableScroll) {
return super.onInterceptTouchEvent(e);
}
return false;
}
}
You have to use layout gravity to make it center & need to change match-parent to wrap_content, also you have to assign layout gravity runtime. try this code:
Adapter item layout:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:descendantFocusability="blocksDescendants"
android:orientation="vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:id="#+id/top_header_rl"
android:background="#color/app_header_color"
android:orientation="vertical">
<TextView
android:id="#+id/textViewSceneKK"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:gravity="center"
android:shadowDx="-1"
android:shadowDy="-1"
android:shadowRadius="1"
android:text="Heder name"
android:textSize="26sp" />
<TextView
android:id="#+id/textViewSceneName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:clickable="false"
android:gravity="center"
android:text="Footer name"
android:longClickable="false"
android:textSize="25sp" />
</LinearLayout>
<!--<View-->
<!--android:id="#+id/filterView"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="match_parent"-->
<!--android:clickable="false"-->
<!--android:longClickable="false" />-->
<View
android:id="#+id/filterViewClick"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="?android:selectableItemBackground"
android:focusable="false"
android:focusableInTouchMode="false" />
</FrameLayout>
Adapter Code:
public class CenterGridView extends RecyclerView.Adapter<CenterGridView.CenterGridViewViewHolder> {
private Context context;
public CenterGridView(Context context){
this.context =context;
}
#Override
public CenterGridViewViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new CenterGridViewViewHolder(LayoutInflater.from(context).inflate(R.layout.new_tiem,parent,false));
}
#Override
public void onBindViewHolder(CenterGridViewViewHolder holder, int position) {
if(position%2==0){
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.RIGHT;
holder.top_header_rl.setLayoutParams(params);
}else{
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.LEFT;
holder.top_header_rl.setLayoutParams(params);
}
}
#Override
public int getItemCount() {
return 20;
}
class CenterGridViewViewHolder extends RecyclerView.ViewHolder{
private LinearLayout top_header_rl;
public CenterGridViewViewHolder(View itemView) {
super(itemView);
top_header_rl = (LinearLayout)itemView.findViewById(R.id.top_header_rl);
}
}
}
Main Activity layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical">
<com.demostudies.CustomRecyclerView
android:id="#+id/tests"
android:layout_width="wrap_content"
android:layout_height="wrap_content"></com.demostudies.CustomRecyclerView>
</LinearLayout>
// Set Adapter
CustomRecyclerView customRecyclerView = (CustomRecyclerView)findViewById(R.id.tests);
customRecyclerView.setHasFixedSize(false);
customRecyclerView.setLayoutManager(new GridLayoutManager(this, 2));
customRecyclerView.setAdapter(new CenterGridView(this));
try this:
it's working for me
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|center_vertical"
>
</androidx.recyclerview.widget.RecyclerView>

How to build custom preference extend android.support.v7.preference library?

In these days i'm working on an app which is contain preference and i tried to put each preferences into a CardView. I can make a custom preference with old version of preference library but when i want to use CardView, I have to use preference library v7.
Screen Shot
As you can see, I made a preference category with CardView. Firstly I made a preference activity with a CardView which is contain a fragment. then i add my preference files in my ActivityPrefrences
public class ActivityPrefrences extends AppCompatActivity {
private int[] prefResId = {R.xml.app_preferences,R.xml.app_preferences};
private int[] fragmentResId = {R.id.fragmentGeneralSetting,R.id.fragmentRtl};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_preference);
if (savedInstanceState == null) {
for(int i=0;i<prefResId.length;i++){
Fragment fragment = new PreferenceDataFragment();
Bundle bundle = new Bundle();
bundle.putInt("PREFERENCE_KEY", prefResId[i]);
fragment.setArguments(bundle);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(fragmentResId[i],fragment).commit();
}
}
}
Fragment Class:
public class PreferenceDataFragment extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener{
#Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
//getPreferenceManager().setSharedPreferencesName("settings");
//getPreferenceManager().setSharedPreferencesMode(Context.MODE_PRIVATE);
Bundle bundle = this.getArguments();
if (bundle != null) {
int resId = bundle.getInt("PREFERENCE_KEY", R.xml.app_preferences);
addPreferencesFromResource(resId);
}
}
}
activity_preference.xml
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbarThumbVertical="#drawable/scrollbar_thumb"
android:scrollbarTrackVertical="#drawable/scrollbar_track"
android:clipToPadding="false"
android:duplicateParentState="false"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="8dp"
app:cardElevation="6dp"
app:cardCornerRadius="6dp"
app:cardBackgroundColor="#android:color/white">
<FrameLayout
android:id="#+id/fragmentGeneralSetting"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="8dp"
app:cardElevation="6dp"
app:cardCornerRadius="6dp"
app:cardBackgroundColor="#android:color/white">
<FrameLayout
android:id="#+id/fragmentRtl"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.v7.widget.CardView>
</LinearLayout>
</ScrollView>
Finally i added my own Custom preference in preference.xml but when i loading this activity on phone, i miss a part of view on screen. as you can see on above image, Gray area is holder and white are is a part of custom preference view.
Now i can't understand why my custom view not fitting in whole area of holder? and i can't use setSummary and setTitle in class, Actually "title" and "summary" not applied on TextViews, I don't know why?
This is my custom preference class
public class RTLCheckBoxPreference extends Preference {
private OnPreferenceClickListener prefListener;
private boolean currentValue = false;
public RTLCheckBoxPreference(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public RTLCheckBoxPreference(Context context, AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
setWidgetLayoutResource(R.layout.prefrence_checkbox);
}
#Override
protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
super.onSetInitialValue(restorePersistedValue, defaultValue);
currentValue = restorePersistedValue ? getPersistedBoolean(false):(Boolean) defaultValue;
}
#Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
holder.itemView.setClickable(false);
holder.itemView.setPadding(0,0,0,0);
RecyclerView.LayoutParams param = (RecyclerView.LayoutParams) holder.itemView.getLayoutParams();
param.setMargins(0,0,0,0);
holder.itemView.setLayoutParams(param);
}
}
This is my custom layout for my prefrence.
<FrameLayout 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:orientation="vertical"
android:minHeight="?attr/listPreferredItemHeight"
android:gravity="center_vertical"
android:paddingRight="?android:attr/scrollbarSize"
android:background="?attr/selectableItemBackground"
android:focusable="true" >
<com.bvapp.widget.HoloButton.HoloButton
android:id="#+id/btnCheckBoxPrefrence"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="15dip"
android:layout_marginRight="15dip"
android:layout_marginTop="6dip">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:background="#drawable/check_box_outline_blank"
android:id="#+id/imgCheckBoxPrefrence"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"/>
<TextView android:id="#android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#color/text_main"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:gravity="right"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:textSize="#dimen/font_norm_size"/>
<TextView android:id="#android:id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#android:id/title"
android:layout_alignRight="#android:id/title"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#color/text_aux"
android:maxLines="4"
android:gravity="right"
android:textSize="#dimen/font_aux_norm_size"/>
</RelativeLayout>
</FrameLayout>
I tried a lot to find my answers, even i tried to set padding and margin to "0" but it's not working. How should I fit my own custom preference in holder and use "title" and "summary" in my custom preferences?

Categories

Resources