I have a LinearLayout that contains several views - when I add or remove it from my view I used the default LayoutTransition.
I'm adding the view to my AppbarLayout - and I added the animations programmatically by setting a new LayoutAnimation on the appbar before adding the view and setting it to null after the view is added - I don't do it using the tag in the xml due to https://code.google.com/p/android/issues/detail?id=191170
The problem is that when i remove it from the view the default animation is done in two parts
all the views inside immediately disappear
the closing of the view is animated from bottom to top
Which change is needed to the LayoutTransition in order to have only the 2nd animation where the view is closed from bottom to top?
CommonsWare answer
Modify its LayoutParams to move it to the end position. Use
getLayoutParams() on the View, cast it to the appropriate type based
on its container, modify the LayoutParams object, then call
setLayoutParams() on the View to commit the changes.
Try this:
final LinearLayout container = (LinearLayout) findViewById(R.id.container);
LayoutTransition transition = container.getLayoutTransition();
transition.disableTransitionType(LayoutTransition.APPEARING);
transition.disableTransitionType(LayoutTransition.DISAPPEARING);
I'm using the TwoWayView library : https://github.com/lucasr/twoway-view to try and implement a horizontal ListView of sorts to overhaul what I had before. (HorizontalScrollView with a horizontally oriented LinearLayout that I add views to)
I want to have a margin before the first item, so there's a blank space at the left when the View is first created. But when scrolled, the blank space would be scrolled and disappear as well. When using a normal ListView it is essentially a HeaderView that I want.
When I implemented the scroll using HorizontalScrollView, I simply programmatically checked the first item and added the margin, which worked since its parent was LinearLayout and accepts margins. But I cannot do this in the getView() of the adapter used for this AdapterView since its LayoutParams do not inherit ViewGroup.MarginLayoutParams
I've also tried setting clipToPadding="false", but the views gets recycled too early, which is unacceptable since the padding I need is noticeably big.
Is there a way to achieve this behavior without moving all the HeaderView code from ListView into the TwoWayView library?
You can try something like this:
on getView(int pos, View convertView, ViewGroup parent){}
{
if (convertView == null)
{ ... }
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT , ViewGroup.LayoutParams.WRAP_CONTENT);
/// To set your margin, you just need to test the position :)
params.setMargins(left, top, right, bottom);
viewHolder.LinearLayout.setLayoutParams(params);
}
Hope this would help you.
I'm having some problems when trying to remove the header from a listView. At first I use addHeaderView() to add it, but when I change to another layout I want it to disappear but removeHeaderView() doesn't work...
I also tried setting visibility to GONE and it doesn't disappear...
What can I do?
Thanks in advance
Try the approach mentioned below..
Android ListView#addHeaderView and ListView#addFooterView methods are strange: you have to add the header and footer Views before you set the ListView's adapter so the ListView can take the headers and footers into consideration -- you get an exception otherwise. Here we add a ProgressBar (spinner) as the headerView:
// spinner is a ProgressBar
listView.addHeaderView(spinner);
We'd like to be able to show and hide that spinner at will, but removing it outright is dangerous because we'd never be able to add it again without destroying the ListView -- remember, we can't addHeaderView after we've it's adapter:
listView.removeHeaderView(spinner); //dangerous!
So let's hide it! Turns out that's hard, too. Just hiding the spinner view itself results in an empty, but still visible, header area.
Now try to hide the spinner:
spinner.setVisibility(View.GONE);
Result: header area still visible with an ugly space:
The solution is to put the progress bar in a LinearLayout that wraps it's content, and hiding the content. That way the wrapping LinearLayout will collapse when its content is hidden, resulting in a headerView that is technically still present, but 0dip high:
<LinearLayout
xmlns:a="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<!-- simplified -->
<ProgressBar
android:id="#+id/spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
Then, set the layout as the header:
spinnerLayout = getLayoutInflater().inflate(R.layout.header_view_spinner, null);
listView.addHeaderView(spinnerLayout);
And when we need to hide it, hide the layout's content, not the layout:
spinnerLayout.findViewById(R.id.spinner).setVisibility(View.GONE);
Now the header disappears from view. No more ugly space at the top!
Most people don't like to use AddHeaderView, however I sometimes found it very convenient, to avoid modifying complex adapters, or if the headers are not very related to them.
With this easy trick you will be able to seamlessly remove/add headers:
I add an empty LinearLayout with orientation vertical, and height wrap_content, as the only Header View (let mListView be the target listView):
LinearLayout mCustomHeaders=new LinearLayout(context);
mCustomHeaders.setOrientation(LinearLayout.VERTICAL);
mListView.addHeaderView(mCustomHeaders);
mListView.setAdapter (.......)
Thenafter, I can add random stuff, anywhere, to the list as header, even when the list is full:
mCustomHeaders.add(myHeaderView1);
mCustomHeaders.add(myHeaderView2);
mCustomHeaders.add(myHeaderView3);
You can also delete all headers, anytime:
mCustomHeaders.removeAllViews(); // will erase all headers
You get the idea .... Hope it helps !
The problem is that you are always creating a new object when you do:
View headerView = someView
So the new view is not the same as the view already added as listView header, try this:
View headerView = inflater.inflate(R.layout.adapter_datatable_saleitem_header, null, false);
headerView.setTag(this.getClass().getSimpleName() + "header");
if (listView.getHeaderViewsCount() > 0) {
View oldView = listView.findViewWithTag(this.getClass().getSimpleName() + "header");
if (oldView != null) {
listView.removeHeaderView(oldView);
}
}
You can check if header count > 0 then remove the header and add it again.
its works fine for me.
View _headerView;
private void function HandleHeaderView(){
if(listView.getHeaderViewsCount() > 0)
{
listView.removeHeaderView(_headerView);
}
/* Add list view header */
_headerView = GetHeaderView();
listView.addHeaderView(_headerView);
}
private View GetHeaderView()
{
View header = getLayoutInflater().inflate(R.layout.header_layout, null);
// TODO: ...
return header
}
Where drawerLogoView is my headerview, here's what I do:
drawerLogoView = mInflater.inflate(R.layout.navigation_drawer_custom_layout, null);
mDrawerList.addHeaderView(drawerLogoView,null,false);
LinearLayout layOut = ((LinearLayout)drawerLogoView.findViewById(R.id.NavProfilePreviewLayout));
layOut.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, 0));
That way, it becomes invisible :D
To show it back, you can use this:
LinearLayout layOut = ((LinearLayout)drawerLogoView.findViewById(R.id.NavProfilePreviewLayout));
layOut.setLayoutParams(newRelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT));
If you are using addHeaderView(), you can't delete your header after that.
So, don't use addHeaderView(). Rather, create your own adapter that
blends your main roster of Views with your header. While my
MergeAdapter will not handle your specific case, you can use it to see
the concept of blending multiple row sources:
https://github.com/commonsguy/cwac-merge
I encountered this problem in a slightly disguised scenario: the ListView I was dealing with came from PreferenceFragment, and the header represents a PreferenceCategory. So, my freedom of setting up the ListView was severely limited. But there were two approaches (partly inspired by other answers on this page). One was to add a custom layout to my PreferenceCategory (using a class that extends android.preference.PreferenceCategory, see Custom PreferenceCategory Headings). But I found an easier workaround: for the first Preference in this PreferenceCategory, I override onCreateView():
#Override public View onCreateView(ViewGroup parent) {
parent.setTop(-parent.getChildAt(0).getTop());
return super.onCreateView(parent);
}
I have a custom view which will be jar'ed up and added into another project. In the view I want to give an option of a button.
Here is what I have in the CustomView class.
final CustomView currentView = (CustomView) findViewById(this.getId());
RelativeLayout.LayoutParams params = (new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT ));
params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
closeButton.setLayoutParams(params);
currentView.addView(closeButton);
This is all wrapped in a RelativeLayout Tag as well as the other objects of the application
Everything compiles however in the CustomView the Button is aligning left instead of right.Any Ideas???
I would guess the problem is your CustomView. It probably doesn't take the entire width of the window, and is just wide enough to fill its children (which, in your case, is the close button). Make sure your CustomView has a fill_parent horizontal layout.
Since your CustomView extends WebView, which, in turn, extends AbsoluteLayout, you can't expect it to handle RelativeLayout's parameters. Instead, it's best you put your customview and your close button inside a RelativeLayout and position them properly.
When adding your closeButton to your currentView you need to supply the LayoutParams as an argument as well in order for them to take effect.
Basically, switch
currentView.addView(closeButton);
with
currentView.addView(closeButton, params);
Since the width of your button is set to wrap_content, you could also try setting its layout_gravity to right.
params.gravity = Gravity.RIGHT;
I have a custom view (an extension of a TextView) that I want to dynamically add to my Layout (don't want to include it in the main.xml file).
The book says to fetch the RelativeLayout using findViewById() in my java code then create a new instance of my custom view, then use addView on the RelativeLayout to add the new view.
I'm not getting any errors, but when I click my button to add the new view, nothing is happening (view isn't being added). Do I need to set additional properties on my custom view (layout width, layout height for example) in order for it to be shown?
EDIT: adding code
// changed to an imageview as I thought it might be easier to see an image
RelativeLayout rel = (RelativeLayout) findViewById(R.id.rellay);
MyCustomImageView mciv = new MyCustomImageView(null);
mciv.setId(5);
LayoutParams p = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
mciv.setLayoutParams(p);
mciv.setImageResource(R.drawable.someImage);
rel.Addview(mciv);
Please post your code where you add the view.
But yes, you might be missing the params for width and height. Try something like
LayoutParams p = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.FILL_PARENT);
txtView.setLayoutParams(p);
or what you would like the width and height to be. Also in xml layout, layout_width and layout_height are required attributes.