My question is simple is a UI/UX design question. I want to get this model for my layout
I have no idea how is this called, want some help and idea for coding this one I tried few options but nothing.
To create this above layout You can use either of FrameLayout or Co-ordinator Layout or the new ConstraintLayout.
This will do it for you.
Refer this link to understand the above design.
<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="xyz.himanshusingh.cryptokoin.ui.display.MainActivity">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:background="#drawable/toolbargradient" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="130dp"
android:layout_below="#+id/toolbar"
android:background="#drawable/toolbargradient" />
<android.support.v7.widget.CardView
android:id="#+id/cardView"
android:layout_width="match_parent"
android:layout_height="150dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="80dp"
app:cardCornerRadius="10dp">
</android.support.v7.widget.CardView>
</RelativeLayout>
and toolbargradient.xml,
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:type="linear"
android:startColor="#f7792e"
android:endColor="#ef246b"
android:angle="180"/>
</shape>
This XML code will almost make the design for you. In place of CardView you can use whatever you want.Like a RecyclerView, DatePicker etc.
Hope this helps :)
Try using a Relative Layout for the image & recycler view and put the recycler view in cardview. This should work for 1st & 2nd view & in 3rd inside a cardview add a calendar & a recycler view below it. Hope this helps
I'm trying to display a shadow under items of a RecyclerView but there is no space between items.
I'm trying to reproduce something like that :
I've implemented a RecyclerView and a FlexboxLayout so items takes the whole place in the screen.
Here is the recycler view declaration:
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listitem="#layout/category_item"
android:clipToPadding="false"
android:paddingEnd="20dp"
android:paddingBottom="20dp"/>
Here is the item layout :
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.flexbox.FlexboxLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/itemContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:justifyContent="center"
android:elevation="8dp"
>
<TextView
android:id="#+id/itemTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawablePadding="20dp"
android:gravity="center"
android:textSize="16sp" />
</com.google.android.flexbox.FlexboxLayout>
And the onBindViewHolder method from the adapter:
#Override
public void onBindViewHolder(final CategoryViewHolder holder, int position) {
if (categories != null) {
Category category = categories.get(position);
holder.itemTitle.setText("Lorem ipsum");
ViewGroup.LayoutParams lp = holder.itemContainer.getLayoutParams();
holder.itemContainer.setBackgroundResource(category.getColor());
if (lp instanceof FlexboxLayoutManager.LayoutParams) {
FlexboxLayoutManager.LayoutParams flexboxLp =
(FlexboxLayoutManager.LayoutParams) holder.itemContainer.getLayoutParams();
flexboxLp.setFlexGrow(1.0f);
}
}
}
Here is what i get:
As you can see, i put a padding so we can see the shadow behind but since there is no space between items, the shadow isn't displayed.
I'd like the shadow to be displayed on top of other items.
I don't know how to make a good looking separation between items otherwise, i've tried with DividerItemDecoration but it doesn't work as expected.
You can try with the custom layout of an adapter. Into the custom layout at the bottom, you can give your border or shadow. It will work for you.
I found a solution here : https://stackoverflow.com/a/35406689/9434800
I've created a gradient resource:
<shape xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:angle="90"
android:centerColor="#color/c1"
android:centerY="90%"
android:endColor="#color/c1_darker"
android:startColor="#color/c1"
android:type="linear" />
</shape>
And i set it as background of my item, this way the top of my items are darker and it seems like it's the shadow of items above them.
I was trying to make shadow effect with Cardview and it is showing the shadow effect in the XML Preview but there is no shadow effect on the Physical Device
Here is the code for the XML of recycler view data item.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:elevation="3dp"
card_view:cardCornerRadius="#dimen/card_album_radius">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:background="?attr/selectableItemBackgroundBorderless"
android:id="#+id/cast_profile_picture"
android:layout_width="match_parent"
android:layout_height="200dp"
android:src="#drawable/image4" />
<TextView
android:paddingLeft="#dimen/album_title_padding"
android:paddingRight="#dimen/album_title_padding"
android:paddingTop="#dimen/album_title_padding"
android:id="#+id/cast_name"
android:textSize="17sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/Title"/>
<TextView
android:paddingBottom="#dimen/songs_count_padding_bottom"
android:paddingLeft="#dimen/album_title_padding"
android:paddingRight="#dimen/album_title_padding"
android:id="#+id/cast_character_name"
android:textSize="13sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/Sub_Title"/>
</LinearLayout>
</android.support.v7.widget.CardView>
This is happening because your RecyclerView is putting your cards immediately next to each other, leaving no room for the system to draw a shadow. You can actually see a tiny shadow at the top and bottom corners of your cards (because the rounded corner leaves a very small amount of space for the system to draw the shadow in).
To leave space for the shadow, you should add an ItemDecoration to your RecyclerView that sets each card's offsets.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recycler = (RecyclerView) findViewById(R.id.recycler);
recycler.addItemDecoration(new MyItemDecoration(this));
...
}
private static class MyItemDecoration extends RecyclerView.ItemDecoration {
private final int offset;
public MyItemDecoration(Context context) {
this.offset = context.getResources().getDimensionPixelSize(R.dimen.card_offset);
}
#Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
outRect.set(offset, offset, offset, offset);
}
}
And define the offset you want as a dimen resource, like this:
<resources>
<dimen name="card_offset">3dp</dimen>
</resources>
Without ItemDecoration:
With ItemDecoration:
try this use app:cardElevation and app:cardUseCompatPadding like this
if required name splace than add this xmlns:app="http://schemas.android.com/apk/res-auto"
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardElevation="5dp"
app:cardUseCompatPadding="true">
I think you are testing your app on Kitkat device. Try to test your app on Lollipop or later device.
Try using:
app:card_elevation="2dp"
I'm having trouble with this layout that is a item in my grid adapter.
I'm using caldroid
I inflate my cell layout in the getview:
R.layout.calendar_view_date_cell.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/rlCalendarViewCell"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white1"
>
<TextView
android:id="#+id/tvCalendarDayNr"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:padding="5dp"
android:text="10"
android:textSize="20sp" />
<View
android:id="#+id/vCellBorder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/selected_border" >
</View>
</RelativeLayout>
I want to use the view that is inside the relativelayout for a border background.
I'm using this method to try and change the background of the cell (to show that this cell of the calendar is the one that has been pressed).
#Override
public void onSelectDate(Date date, View view) {
View vCellBorder = (View) view.findViewById(R.id.vCellBorder);
vCellBorder.setBackgroundResource(R.drawable.selected_border);
Toast.makeText(getApplicationContext(), ""+(date),
Toast.LENGTH_SHORT).show();
}
The weird thing is, in my date_cell preview I can already see the selected border. But when I run my app, I only see the background of the Relativelayout (color/white1).
If I change my method to:
#Override
public void onSelectDate(Date date, View view) {
view.setBackgroundResource(R.drawable.selected_border);
Toast.makeText(getApplicationContext(), ""+(date),
Toast.LENGTH_SHORT).show();
}
This up here works. But I dont want it like this, because I want the ability to change different backgrounds for the different layers of the layout.
I suspect that this is because the base class view doesn't know how to layout properly.
I would change the View to an ImageView and place it before the textview in the layout like this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/rlCalendarViewCell"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white1"
>
<ImageView
android:id="#+id/vCellBorder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/selected_border" />
<TextView
android:id="#+id/tvCalendarDayNr"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:padding="5dp"
android:text="10"
android:textSize="20sp" />
</RelativeLayout>
Also in the code i would hide/unhide the view rather than changing its drawable
so
#Override
public void onSelectDate(Date date, View view) {
View vCellBorder = (View) view.findViewById(R.id.vCellBorder);
vCellBorder.setVisibility(View.VISIBLE);
Toast.makeText(getApplicationContext(), ""+(date),
Toast.LENGTH_SHORT).show();
}
and obviously the view would start as GONE or INVISIBLE
My view was getting 0dp width and height. So thats why the background was not showing.
In the end I changed my view into a linearlayout and put my textview inside of it. and match_parent is working now. The 0dp was giving me the hint.
I've got a view that is effectively is a button. Here is its XML layout (add_new.xml)
<?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:orientation="horizontal">
<Button
android:id="#+id/buttonNew"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/bText"
android:onClick="addNew"/>
</LinearLayout>
When I set its visibility to GONE like this
v = getActivity().getLayoutInflater().inflate(R.layout.add_new, null);
v.setVisibility(View.GONE);
it disappears but still occupies space. Like this:
This button is a header in the ListView, which is defined by this xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/porno" >
<ImageView
android:id="#+id/icon"
android:layout_width="30dp"
android:layout_height="40dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="10dp"
android:layout_marginTop="4dp"
android:src="#drawable/ic_launcher">
</ImageView>
<TextView
android:id="#+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#+id/label"
android:textSize="20dp" >
</TextView>
</LinearLayout>
And I dont want it to occupy an additional list item when its visibility is set to GONE. As it is stated in the documentation.
GONE - This view is invisible, and it doesn't take any space for
layout purposes.
Any ideas on how to make it NOT occupy space?
Thanks,
Dennis xx
P.S. My listview is inside of a FoldersFragment ListFragmentand here is the xml of my MainActivity where FoldersFragment is presented
<?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:orientation="horizontal" >
<fragment
android:id="#+id/foldersFragment"
android:layout_width="200dip"
android:layout_height="match_parent"
class="com.example.fragments.FoldersFragment" >
</fragment>
<fragment
android:id="#+id/detailFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.example.fragments.DetailFragment" >
</fragment>
</LinearLayout>
This is an Android bug in my opinion, we just fix this issue doing this:
<FrameLayout android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout android:id="#+id/layout_to_hide"
android:layout_width="match_parent"
android:layout_height="wrap_content">
//Put here your views
</LinearLayout>
</FrameLayout>
Just hide LinearLayout with id LAYOUT_TO_HIDE with Visible.GONE and then root FrameLayout will collapse its height giving you a "hidden" with non-blank-space header.
set layout_width and layout_height to 0 where you want to hide item, by doing this
//if item's parent layout is LinearLayout, change according to your item xml
holder.itemView.setLayoutParams(new LinearLayout.LayoutParams(0,0));
All replies in this thread are suggesting a new wrapper view, which comes at a cost. The correct way of hiding a view completely is to set margins to 0 while setting visibility to GONE. In this code sample, cardView is the view I am trying to hide. The direct parent of cardView is RecyclerView, that's why we are using RecyclerView.LayoutParams - remember to replace with the right layout params.
if (cardView.getVisibility() != GONE) {
cardView.setVisibility(GONE);
RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) cardView.getLayoutParams();
layoutParams.setMargins(0, 0, 0, 0);
cardView.setLayoutParams(layoutParams);
}
If this is stil needed, there is a great way to deal with it:
parentView.removeView(childView);
here an example:
final WhatEverLayout parentView, childView;
parentView = (WhatEverLayout)findViewById(R.id.parentView_xml);
childView =(WhatEverLayout)findViewById(R.id.childView_xml);
parentView.removeView(childView);
What you can do is set an if statement, whenever the condition to set the visibility to "GONE", set the view as wrap content and your space will be free, I did it and it worked for a seekbar
This is my solution. Create a new layout file with name "special.xml", copy the code to the file.
<?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"
android:visibility="gone">
</LinearLayout>
Use condition to inflate the empty layout inside the newview. Don't Use the view.setVisibility(View.GONE);.
if(true){
view=mInflater.inflate ( R.layout.special,parent, false );
}else{
view=mInflater.inflate(R.layout.normal,parent,false);
// The view that you want to be visible
}
header_layout.xml:
<?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">
<LinearLayout
android:id="#+id/mHeaderView"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/mNoHelpLayout"
android:layout_width="match_parent"
android:layout_height="176dip"
android:background="#ffffffff"
android:gravity="center"
/>
</LinearLayout>
</LinearLayout>
java code:
LayoutInflater mInflater =(LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View outerView = mInflater.inflate(R.layout.header_layout, null);
mHeaderView = (LinearLayout) outerView.findViewById(R.id.mHeaderView);
use mHeaderView.setVisiable() to control visiable not the outerView.setVisiable().
it works for me.
If you want to show itemView
if (ItemBean.isShow())
{
holder.itemView.setVisibility(View.VISIBLE);
holder.itemView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
} else
{
holder.itemView.setLayoutParams(new LinearLayout.LayoutParams(0, 0));
holder.itemView.setVisibility(View.GONE);
}
You can use :
viewToHide?.postDelayed({ viewToHide?.visibility = View.GONE }, durationInMillis)
For me, it worked if I did the showing/hiding on the next run loop.
parentView.post {
childViewToHide.visibility = View.GONE
}
I had similar issue when using TransitionManager.beginDelayedTransition(), in the Layout Inspector tool I see that the view is Gone, but it still taking space, I think it is bug in Android, a workaround is to execute the visibility block with View.post(Runnable action)
In my case I was using an animation and in my anim, I had the flag
android:fillAfter="true"
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true">
<translate
android:duration="300"
android:fromYDelta="100%"
android:toYDelta="0%" />
<alpha
android:duration="150"
android:fromAlpha="0"
android:toAlpha="1" />
</set>
This caused the view to be set as invisible even when it was being set to GONE.
After removing android:fillAfter="true" I had no more issues and the view was then properly being set to GONE.
Simplest way is to force the parent view to remeasure its own height after children visibility changed.
Try something like this :
parentView.setLayoutParams(new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT));
in this case, parent view is a LinearLayout.
A generic and easy solution is to avoid all thuse heck of code:
You need to add a Container Layout or a Parent Layout over your set of views that you want to hide. It can be anything like CardView or FrameLayout or etc.
Just it has to be a parent for that view that you want to hide. And you wont get all those white spaces. Coz it will consider the entire container to hide instead of considering individual views to HIDE thus, avoiding the white spaces.
Setting view padding and margins to 0 and then set view visibility to gone solved my problem.
I don't think this is a bug.. Just use GONE to make the empty space disappear.
CSS does the same thing. Try display: block vs visibility: hidden.