I have a scrollview in my android app that supports overscroll and has a nice bounce effect. What I would like to do is add a view that is initially hidden to the user, but if they scroll up beyond the initial view, then they can see it. How can I do this? Is it possible to do this using just xml?
You can place the initial view and the additional view in a LinearLayout, and when the scroll view is created, you can immediately scroll downwards to the initial view. You can set the initial scroll offset using the xml attribute android:scrollY.
By code you can definitely achieve this. In this sample code I have 15 buttons in srollview. And hide 1st button for initial display.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final ScrollView hscrollViewMain = (ScrollView)findViewById(R.id.sview);
hscrollViewMain.post(new Runnable() {
public void run() {
Button bt2 = (Button)findViewById(R.id.button2);
int nY_Pos = bt2.getTop();
// scroll to top of bt2
hscrollViewMain.scrollTo(0,nY_Pos);
}
});
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/sview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button
android:layout_width="fill_parent"
android:id="#+id/bt1"
android:layout_height="wrap_content"
android:text="Button 1" />
<Button
android:id="#+id/button2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Button 2" />
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Button 3" />
.
.
.
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Button 15" />
</LinearLayout>
</ScrollView>
Related
I want to do something similar to a Map behavior where I have a large Image (bigger than the phone screen) and a group of buttons I want to put over special XY locations over the image, and when the user scrolls the image (horizontally and vertically), the buttons keep the same position over the image (like markers do). Then the user can click over a button and open a new activity.
I want to do this in xml. Any suggestion?
I cant figure out how to attach the buttons with the image XY positions:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/map_view"
android:background="#drawable/myImage"/>
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Position 1"
android:id="#+id/radioButton" />
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Position 2"
android:id="#+id/radioButton2" />
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Position 3"
android:id="#+id/radioButton3" />`
/>
</RelativeLayout>
</ScrollView>
Instead of scrollview you should change imageview position on touch. If user touches top-down , imageview position should goes to negative direction same as top-down pixels. Therefore your imageview can move to right-left as well.
Get the touch position inside the imageview in android
Android move view on touch event
Here, make sure the the ImageView should always be larger than the screen as you say.
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/map_view"
android:layout_width="1800px"
android:layout_height="1800px"
android:background="#drawable/the_large_image"/>
<RadioButton
android:id="#+id/radioButton"
android:layout_marginTop="20dp"
android:layout_marginLeft="50dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Position 1"/>
<RadioButton
android:id="#+id/radioButton2"
android:layout_marginTop="200dp"
android:layout_marginLeft="50dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Position 2"/>
<RadioButton
android:id="#+id/radioButton3"
android:layout_marginTop="80dp"
android:layout_marginLeft="60dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Position 3"/>
</RelativeLayout>
</ScrollView>
Thanks to #Sheychan that gave me some clue for getting this as I wanted.
First of all: the xml. Use 2 scroll views (one main that is vertical, and another horizontal), so that we can get horizontal and vertical scrolling. Then a RelativeLayout so that we can put the radiobuttons over the image in desired positions. Is important the "src" and "scaleType" in image so that we can get correct image dimensions. Here is the code for xml
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/svVertical">
<HorizontalScrollView android:id="#+id/hsvHorizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:isScrollContainer="true">
<ImageView
android:id="#+id/map_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/imagen"
android:scaleType="centerCrop"/>
<RadioButton
android:id="#+id/radioButton"
android:layout_marginTop="20dp"
android:layout_marginLeft="50dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Position 1"/>
<RadioButton
android:id="#+id/radioButton2"
android:layout_marginTop="200dp"
android:layout_marginLeft="50dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Position 2"/>
<RadioButton
android:id="#+id/radioButton3"
android:layout_marginTop="80dp"
android:layout_marginLeft="60dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Position 3"/>
</RelativeLayout>
</HorizontalScrollView>
</ScrollView>
But with this solution we got odd scrolling (only vertical or horizontal, not both at the same time: call it "diagonal" scrolling). To resolve this: a simple override on Activity holding this layout:
ScrollView scrollY;
HorizontalScrollView scrollYChild;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
scrollY = (ScrollView)findViewById(R.id.svVertical);
scrollYChild = (HorizontalScrollView)findViewById(R.id.hsvHorizontal);
}
#Override
public boolean dispatchTouchEvent(MotionEvent event) {
scrollYChild.dispatchTouchEvent(event);
scrollY.onTouchEvent(event);
return super.dispatchTouchEvent(event);
}
This start working better, but still in an odd way. Is like the move "jumps" while scrolling.
The solution: take away the action bar:
On the Manifest, add the "NoActionBar" theme in the application tag (or the activity tag)
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#android:style/Theme.Holo.NoActionBar.Fullscreen" >
...
</application>
But, be careful, cause the activity must not be an "ActionBarActivity", you must change it to "Activity".
And, just in case, by Android recommendation, add a compatible old SDK versions with a "hide the status bar" on the OnCreate of the Activity.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// If the Android version is lower than Jellybean, use this call to hide
// the status bar.
if (Build.VERSION.SDK_INT < 16) {
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
setContentView(R.layout.activity_main);
scrollY = (ScrollView)findViewById(R.id.svVertical);
scrollYChild = (HorizontalScrollView)findViewById(R.id.hsvHorizontal);
}
And that's all folks :) Hope it helps you as it helped me.
I'm trying to create a custom view in android that I can use in the same way as a LinearLayout. The custom view should add two TextView on top of whatever I add inside the layout. How can I control the visibility of the contents of my custom view? I have to be able to add contents at design time and at run time visibility of that nested contents should be toggled, but not those two TextViews.
My question is somewhat similar to this one which didn't really get a satisfactory answer.
I've created a custom view that extends LinearLayout:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal"
>
<TextView
android:id="#+id/txt_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="My title"
android:layout_marginLeft="10dp"
/>
<TextView
android:id="#+id/txt_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:layout_marginRight="10dp"
android:text="My button"
android:onClick="txtButton_onClick"
android:clickable="true"
/>
</LinearLayout>
<LinearLayout
android:id="#+id/all_contents"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="visible"
android:layout_marginTop="10dp"
/>
<!-- This is where I _want_ to add all nested contents to make it easy to toggle its visibility -->
</merge>
All nested content I want to be contained in the LinearLayout at the bottom, so that when I click txt_button I can set visibility on all_contents to gone and make that disappear. I still want txt_title and txt_button to continue being visible, so I can toggle showing the content or not.
The custom view is supposed to be called like this:
<org.my.app.view.SlidingLayoutView
android:id="#+id/slv_date_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
custom:titleString="Date and time"
custom:buttonString="Change">
<!-- This is where all nested contents should go -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Example nested content"
/>
</org.my.app.view.SlidingLayoutView>
What I don't get is how to decide that nested contents goes into the all_content LinearLayout. Or am I thinking about this all wrong? Does nested content end up at the very bottom of the custom view, and if so how do I toggle its visibility and not my two TextView?
By on top of do you mean above in the linear layout? I think that your xml should work if you take out the all_contents LinearLayout, things will be added to the LinearLayout. Make your xml like this.
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal"
>
<TextView
android:id="#+id/txt_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="My title"
android:layout_marginLeft="10dp"
/>
<TextView
android:id="#+id/txt_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:layout_marginRight="10dp"
android:text="My button"
android:onClick="txtButton_onClick"
android:clickable="true"
/>
</LinearLayout>
<!-- This is where I _want_ to add all nested contents to make it easy to toggle its visibility -->
</merge>
I would add two methods in the class like this which you can use to toggle the visibility of your contents or the textViews at the top:
public void setTopTextViewVisibility(int visibility){
for(int i = 0; i < getChildCount(); i ++){
View view = getChildAt(i);
if(view.getId() == R.id.txt_title || view.getId() == R.id.txt_button){
view.setVisibility(visibility);
}
}
}
public void setContentVisibility(int visibility){
for(int i = 0; i < getChildCount(); i ++){
View view = getChildAt(i);
if(!(view.getId() == R.id.txt_title || view.getId() == R.id.txt_button)){
view.setVisibility(visibility);
}
}
}
I would use a FrameLayout, you can put a linear layout inside the frame and then put all your views inside that and make a new frame for each group of views.
Here's the basic structure of a menu screen I did where once you click a button it shows a new frame with more options.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/mayne" >
<FrameLayout
android:id="#+id/frameMain" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/textView1" />
<Button
android:id="#+id/button1" />
<Button
android:id="#+id/button2" />
</RelativeLayout>
</FrameLayout>
<FrameLayout
android:id="#+id/frameDiff" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="#+id/btnMed" />
<Button
android:id="#+id/btnHard" />
<Button
android:id="#+id/btnEasy" />
<TextView
android:id="#+id/textView2" />
<Button
android:id="#+id/btnCancel" />
</RelativeLayout>
</FrameLayout>
I'm having troubles getting my head around how to create add animation to a LinearLayout that is translucent. There are two views with opacity and a moving background (Google map if it is of importance). View1 is a LinearLayout and view2 is being added to view1. However when adding view2 it is seen through view1 (see left animation below).
Is there any way I can prevent this to achieve my animation correctly? (goal: see animation on the right) Keep in mind that the background is changing and is not a fixed picture.
Best regards
Rawa
I imagine my comment may not have been entirely clear, so I put together a simple example to better explain and demonstrate. As I'm uncertain as to what your Views will be, I've left them rather generic, and set some hard-coded properties you will want to change.
main.xml layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/stripes_diag" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#00000000" >
<TextView android:id="#+id/view2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:background="#88ffffff"
android:textColor="#000000"
android:textSize="40sp"
android:text="Lorem Ipsum" />
</LinearLayout>
<View android:id="#+id/view1"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#88ffffff" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Animate"
android:onClick="onClick" />
</LinearLayout>
</RelativeLayout>
MainActivity class:
public class MainActivity extends Activity
{
View view1, view2;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
view1 = findViewById(R.id.view1);
view2 = findViewById(R.id.view2);
}
public void onClick(View v)
{
view2.setY(view2.getHeight());
ObjectAnimator anim = ObjectAnimator.ofFloat(view2, "y", 0);
anim.setDuration(1500);
anim.start();
}
}
A look at the effect:
I'm trying to start an application and I'm kind of lost on how to do what I want.
This is what I want
Both red panels should be able to slide to the sides and the white one should expand if one of them (or both) them is collapsed, occupying that panel space.
When I have the red panels on the screen, the white panel show all the content and not be under any of the panels.
What have I tried so far:
I started by trying with two SlidingDrawers, but the white panel got behind the red ones, so, no luck there.
After that I tried with 2 LinearLayouts (red panels) and a RelativeLayout (white panel), and tried to change width of the layouts with buttons (like is on the image on top). This caused always problems that I didn't know how to resolve.
Suggestions?
Edit:
xml of the SlidingDrawer example:
<LinearLayout
android:id="#+id/LinearLayout01"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:gravity="bottom"
android:background="#FFFFFFFF">
<SlidingDrawer
android:layout_width="100dip"
android:id="#+id/SlidingDrawer"
android:handle="#+id/slideHandleButton"
android:content="#+id/contentLayout"
android:layout_height="fill_parent"
android:orientation="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:id="#+id/contentLayout"
android:orientation="horizontal"
android:background="#C0C0C0"
android:layout_height="wrap_content">
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Meio"
android:layout_toRightOf="#+id/buttonEsq" />
</LinearLayout>
<Button
android:layout_width="30dip"
android:layout_height="30dip"
android:id="#+id/slideHandleButton"
android:background="#drawable/arrowup">
</Button>
</SlidingDrawer>
</LinearLayout>
And the xml of the LinearLayout example:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<RelativeLayout
android:id="#+id/relativeLayout1"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:layout_toLeftOf="#+id/linearLayout3"
android:layout_toRightOf="#+id/linearLayout1"
android:background="#FFFFFFFF">
<Button
android:id="#+id/buttonEsq"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="v--" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Meio"
android:layout_toRightOf="#+id/buttonEsq" />
<Button
android:id="#+id/buttonDir"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/textView1"
android:text="--v" />
</RelativeLayout>
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="50dip"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:background="#FFFF0000">
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Esquerda" />
</LinearLayout>
<LinearLayout
android:id="#+id/linearLayout3"
android:layout_width="50dip"
android:layout_height="fill_parent"
android:layout_alignParentRight="true"
android:background="#FFF00000">
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Direita" />
</LinearLayout>
</RelativeLayout>
The android code (the commented part is the code of the 1st example):
public class Main extends Activity {
Button slideHandleButton;
Button slideHandleButtonLeft;
Button slideHandleButtonRight;
SlidingDrawer slidingDrawer;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mainlayouts);
/* slideHandleButton = (Button) findViewById(R.id.slideHandleButton);
slidingDrawer = (SlidingDrawer) findViewById(R.id.SlidingDrawer);
slidingDrawer.setOnDrawerOpenListener(new OnDrawerOpenListener() {
#Override
public void onDrawerOpened() {
slideHandleButton.setBackgroundResource(R.drawable.arrowdown);
}
});
slidingDrawer.setOnDrawerCloseListener(new OnDrawerCloseListener() {
#Override
public void onDrawerClosed() {
slideHandleButton.setBackgroundResource(R.drawable.arrowup);
}
});*/
slideHandleButtonLeft = (Button) findViewById(R.id.buttonEsq);
slideHandleButtonLeft.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
LinearLayout lll = (LinearLayout) findViewById(R.id.linearLayout1);
RelativeLayout.LayoutParams params=new RelativeLayout.LayoutParams(50, LinearLayout.LayoutParams.FILL_PARENT);
lll.setLayoutParams(params);
}
});
}
}
SlidingDrawer can only slide in from the right or the bottom, it is unable to slide in from the top or the left. You can try the answer from this question: Android SlidingDrawer from top? or you can get try rewrite the source code http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/1.5_r4/android/widget/SlidingDrawer.java.
However, a SlidingDrawer wont allow
the white panel show all the content and not be under any of the panels
as it will slide over the white panel
The only solution I can think of is to use a series of scale/translate, translate the left or right panel off-screen and set visibility to gone, while at the same time scale the center panel out in the direction of whichever red panel is being removed.
I tried to make a similar prototype some time ago and used this method but the scale animations looked terrible, not to mention the onAnimationEnd listener doesn't work, you'll have to extend a LinearLayout and override onAnimationEnd there for it to work.
I want to create a following kind of layout in android , rite now i have created with fixed height of listview which is causing a problem with different dimension of screens of mobiles.
Initially when this screen appears a button will be at the bottom side only with empty listview and as an when the items will get added in a list view , it grows but button will remain steady at the bottom.
so far i have written following code
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ImageView
android:id="#+id/cText"
android:src="#drawable/c_text"
android:visibility="visible"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="50dip"
/>
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:drawSelectorOnTop="false"
/>
<ImageButton
android:id="#+id/cBtn"
android:layout_width="150dip"
android:layout_height="52dip"
android:src="#drawable/preview"
android:layout_alignParentTop="#+id/list"
android:layout_gravity="center_horizontal"/>
</RelativeLayout>
Try this
< ?xml version="1.0" encoding="utf-8"?>
< RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<ImageButton
android:id="#+id/cBtn"
android:layout_centerHorizontal="true"
android:layout_width="150dip"
android:layout_height="52dip"
android:src="#drawable/preview"
android:layout_alignParentBottom="true"
/>
<ListView
android:id="#+id//listview01"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="#+id/cBtn"
android:layout_marginBottom="10dip"
/>
< /RelativeLayout>
You can add a Button as a footer to List View. The sample code sinppet is shown below
Step1: Create a Button
<Button android:id="#+id/footer" android:gravity="center"
android:layout_gravity="center"
android:text="My Footer"
android:layout_width="wrap_content"
android:layout_height="0dp" android:layout_weight="1"/>
Step2: Make it as Footer to the List View
ListView myList;
View footerView;
ViewGroup footerViewOriginal = (ViewGroup) findViewById(R.id.footer);
footerView = inflater2.inflate(R.layout.footer,footerViewOriginal);
footerView.findViewById(R.id.footer);
myList.addFooterView(footerView, null, true);
Step3: Create on ClickListener and write the action what you want to perform
footerView.findViewById(R.id.footer).setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
return false;
}