I'm playing around with 2D drawing within a custom view. So far I've got it drawing what I want(Point data from an array) but I want the drawing to scale and be able to extend it beyond the screen(such that 1 second of data per screen width). The method I'm using for drawing relies on getHeight and getWidth to set the bounds of the information in the screen. I'm using the screens width to extend the canvas in onDraw to several screen widths in size(depending on the time of the data).
I've been unable to find a way of drawing that will allow me to scroll horizontally, and support a zoom like function... is there an easy way of doing this? ScrollView doesn't do Horizontally, and when I go beyond the screen it just get's cut off. My layout so far is
<HorizontalScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<view class="com.box.sand.SandGraph$GraphView"
android:id="#+id/graph"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
</HorizontalScrollView>
But when I put this in, the onDraw of my view never get's called.
This may solve your problem.
Although I doubt that it has a zoom function, you should be able to implement the rest of what you're asking for using this.
EDIT:
The hierarchy would go as follows:
<HorizontalScrollView ... >
<LinearLayout android:orientation="horizontal" >
<Content goes here />
</LinearLayout>
</HorizontalScrollView>
Related
I am looking for solution as on images bellow:
I need to have two resizable views in one layout.
User just needs to move separation line to the top (ScrolView B becames higher) or to the bottom (ScrolView A becames higher).
What is the best solution, which gives this behavior? I know that I can extends from ScrollView and override public boolean onTouchEvent(MotionEvent ev) and protected void onDraw(Canvas canvas), but may be there is more simple solution. I want to avoid calculation the math of moving. Thank you for any information.
If you want to solve this problem quickly, I suggest you use Split Pane Layout.
Usage :
<com.mobidevelop.spl.widget.SplitPaneLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:spl="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:id="#+id/splitPaneLayout"
android:layout_height="match_parent"
spl:splitterSize="12dp"
spl:orientation="vertical"
spl:splitterPosition="50%"
spl:splitterBackground="#781b23">
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="" />
</ScrollView>
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:text=""/>
</ScrollView>
</com.mobidevelop.spl.widget.SplitPaneLayout>
I solved your problem by creating two xmls for portrait and landscape mode. For portrait mode, i set the panel's orientation as vertical by adding spl:orientation="vertical" and for lanscape mode, i set the panel's orientation as horizontal by adding spl:orientation="horizontal".
After doing all this, I got the look like below.
Made this into an answer.
You basically want the split screen view from Android N. You could base your code off the open source implementation in SystemUI:
http://androidxref.com/7.1.1_r6/xref/frameworks/base/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
Along with this for the handle:
http://androidxref.com/7.1.1_r6/xref/frameworks/base/packages/SystemUI/src/com/android/systemui/stackdivider/DividerHandleView.java
You can throw away all code that has to do with stacks (which is the row of screenshots off different activities in your history), buss events and anything that has to do with running another activity, such as the code for Vsyncing between apps (mSurfaceFlingerOffsetMs).
It should leave you with quite small and easy to use classes.
Consider the following layout:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/bg1" >
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/bg2" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<!-- some views here -->
</LinearLayout>
</FrameLayout>
I'm using it to have bg2 on top of bg1 while bg2 remains completely independent, such that I can apply e.g. a tween alpha animation to it without affecting anything else.
bg1 and bg2 are XML drawables. Obviously, they're supposed to be scaled to their respective View's dimensions. This is normally the case and it doesn't seem to make much sense to specify their dimensions explicitly.
Unfortunately, on Android versions prior to 3/API 11, it looks as if the size of bg2 will be zero. Maybe the two-phase layout measurement is buggy (note how bg2 is supposed to inherit its height from its parent, which in turn needs to adjust to the LinearLayout´s height and propagate that information to the View containing bg2). Or maybe the View won't accept its parent's height (although I tried ImageView which changed nothing).
The Layout you see is really used for items in a list.
The XML drawables are stateful and use gradients.
Can you think of an approach which would also work for Android API 8 to 10?
A bit of testing (subclassing View, overriding onMeasure() and onLayout()) reveals that FrameLayout is broken in this respect in older Android versions.
Since FrameLayout fails to pass its own height down the hierarchy in this scenario (the View will always see 0 both with onMeasure() and onLayout()) there is no obvious way to work around this problem by subclassing.
The question then was, is there another way to overlay the two views which Android 2.2 aka API 8 can handle correctly.
And alas, there is. The same can be achieved with a RelativeLayout, which involves much more overhead of course, though the actual increase in rendering effort should be limited.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/bg1" >
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignTop="#+id/item"
android:layout_alignBottom="#+id/item"
android:background="#drawable/bg2" />
<LinearLayout
android:id="#+id/item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
</LinearLayout>
</RelativeLayout>
After much research on both SO and google, I haven't seen any one with exactly the same problem I am experiencing, so here it is:
I recently redid the entire UI on an android app. For the most part, I made only cosmetic changes to each of the screens. They appear in the UI editor of eclipse perfectly as expected. However, directly after doing this, two of the screens stopped being laid out correctly on both all tested devices and the emulator.
Now, the big problem one these two screens was that the root level LinearLayout didn't appear to be actually honoring the fill_parent for either layout_height or layout_width. it looks like it's being measured as if it were set to wrap_content instead. It only takes up about 70% of the screen - which is just enough to wrap the individual elements inside the root LinearLayout. I would post an image, but as a new user, I am not allowed to.
The layout isn't stretching to fill the screen. Here's the code for layout, except that there are a few more in the LinearLayouts containing a TextView and an EditText.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#FF000000"
android:orientation="vertical" >
<TextView
style="#style/sans.white.16.bold"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="4dp"
android:text="#string/edit_account" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<com.teamunify.ondeck.widget.TUTextView
style="#style/sans.white.14"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="#string/first_name" />
<com.teamunify.ondeck.widget.TUEditText
android:id="#+id/acc_editor_first"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:selectAllOnFocus="true"
android:singleLine="true" />
</LinearLayout>
I think the root LinearLayout should be filling both height and width. I've used this same layout many MANY times in our app without problems. (A quick count revealed that I used 76 LinearLayouts in our app, and all but two of them are working.)
At first, I suspected that perhaps our custom classes measure was wrecking things, so I changed the layout to use all plain EditTexts, but there was no change. I double checked the activity, but it isn't doing anything except to load this xml. So, in desperation, I redid the layout like so:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#FF000000"
android:orientation="vertical" >
<TextView
style="#style/sans.white.16.bold"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center|top"
android:paddingTop="4dp"
android:text="#string/edit_account" />
</LinearLayout>
After that, The words Edit Account appear with a black background mashed into the upper left corner. Clearly, the LinearLayout isn't filling the parent.
Long story short, I am asking how to fix this so that the LinearLayout fills the screen as expected.
I am at a complete loss as to why this is happening, and I am certainly hoping that someone on SO has an idea. This has got me pulling my hair out!
Try setting fixed width and height for the root layout.
Then only you will be able to debug who is driving length and width. It is very much possible that parent activity or background activity is setting dimensions. Once you identify the root cause you can go back to original settings.
As of now from your code snippet given here, nothing wrong here
If you use a custom activity as a container to other activities for some reason (In our case, we were recreating the look of our iOS app, and needed a custom menu to show up along the button side of the screen) the window manager seems to get a bit confused with what the actual height and width of the nested activities should be. A call to fillparent or matchparent ends up wrapping the content instead.
We ended up changing the behavior of several methods in our container activity class to make this work.
I've to design a UI for an Android app where i've 10 vertical tiles containing image and text(the 2 big boxes in the picture) and on clicking a tile, it disappears and is replaced by scrollable gridview containing 6 elements(shown in the centre of figure below) on the same page. (shown by an animation)
Here is a snapshot of the view I'm trying to explain. This images shows only 2 out of 10 tiles and a gridview which appears on click Each of the white box contains image and text. I'm not good at designing, so a detailed answer of implementing this would be appreciated. Thanks.
There is not much details in your question, even the picture does not clarify everything, but here is a stab at it.
Not sure what you mean when you say the tiles "expand" further, do you expect to see the six tiles in the middle to appear at that time or are they always there? if they appear, would that be animated?
To achieve the picture you have, you should probably get a RelativeLayout at the top level.
That's just because you have this date TextView on the top right and the handle to a SlidingDrawer at the bottom. You can set the background of that RelativeLayout with your wallpaper theme and I guess the blue bar on top if that's static.
Then inside this top-leve RelativeLayout you have a LinearLayout with an horizontal orientation. This one will contain the three "windows" on your picture.
In that horizontal LinearLayout, first you have another LinearLayout with a vertical orientation, then a ViewPager and then another vertical LinearLayout similar to the first one (not sure how the right part is different from the left one or that is supposed to be a complete mirror... ?).
So in summary:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="#+id/top_level"
android:layout_height="fill_parent"
android:layout_width="fill_parent">
<TextView
android:id="#+id/date_text"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:paddingTop="..." // fill in some space to offset from the top of the screen
android:paddingRight="..." // same thing to keep it off the right edge
/>
<LinearLayout
android:layout_height="..." // set the height of your content in the center of your screen
android:layout_width="fill_parent"
android:layout_below="#+id/date_text"
android:orientation="horizontal" >
<LinearLayout
android:layout_height="fill_parent"
android:layout_width="wrap_content"
android:orientation="vertical" >
< add here some of the stuff you have above your tile like that RSS icon and so on />
<ListView
android:id="#+id/tile_list"
android:layout_height="fill_parent"
android:layout_width="fill_parent"/>
</LinearLayout>
<ViewPager
android:id="#+id/pager"
android:layout_height="fill_parent"
android:layout_width="0dp"
android:layout_weight="1" // so that will fill the remaining space between the left and the right parts
/>
<LinearLayout
android:layout_height="fill_parent"
android:layout_width="wrap_content"
android:orientation="vertical" >
< add here some of the stuff you have above your tile like that RSS icon and so on />
<ListView
android:id="#+id/tile_list"
android:layout_height="fill_parent"
android:layout_width="fill_parent"/>
</LinearLayout>
</LinearLayout>
<SlidingDrawer
android:id="#+id/drawer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:handle="#+id/drawer_handle"
android:content="#+id/drawer_contents">
<ImageView
android:id="#+id/drawer_handle"
android:src="#drawable/image for the tab..."
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</ImageView>
<Another Layout for the content of the drawer
android:id="#+id/drawer_contents"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
....
</Close that layout>
</SlidingDrawer>
</RelativeLayout>
From there, there is still quite a few things to fill up and some code to write to fill the lists of tiles (on the left and right), handle when the user click on an item, and then also display the content of the ViewPager in the middle of the screen. You'll probably want to use a GridLayout in each page there.
If you need to hide that ViewPager until the user click on some tile, you can set the visibility to hidden and change it in your code.
UPDATE
Now there is more information on how this moves......
OK, so keep the top level RelativeLayout with the date and the SlidingDrawer at the bottom.
In the middle part, you can use the HorizontalListView that was put together by this person: How can I make a horizontal ListView in Android?, the code and instructions and example can be found here: http://www.dev-smart.com/archives/34
Then you need to create your own Adapter to populate that List. You can base it off the BaseAdapter (that decision is more dependent on how your images / information is stored).
In the getView function of that Adapter, can have a layout where both the collapsed and expanded views are combined into one FrameLayout, but only one is visible at a time. It will look like something like this:
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="fill_parent" // assuming the HorizontalListView is set with the right height
>
<LinearLayout
android:id="#+id/collapsed_view"
android:layout_height="fill_parent"
android:layout_width="wrap_content"
android:orientation="vertical" >
< add here some of the stuff you have above your tile like that RSS icon and so on />
</LinearLayout>
<ViewPager
android:id="#+id/expanded_view"
android:layout_height="fill_parent"
android:layout_width="0dp"
android:layout_weight="1" // so that will fill the remaining space between the left and the right parts
android:visibility="gone"
/>
</FrameLayout>
In the list adapter, you will need to set proper tags to the different views, so when a user clicks on one image, you know which one was clicked. To expand one view, you change the visibility of the LinearLayout to gone and the one of the ViewPager to visible.
If there should only be only one expanded at a time, you can have a state variable in your Adapter to say which one it is and set the visibility properties correctly for all the views in the list. Then you call invalidate on the ListView to have it refreshed.
There is quite a bit of code to write to do all this, but if you keep it organized, it should not be too bad....
I am trying to develop a block representation with inputs and outputs.
The main ideia is:
A user can add outputs/inputs
A user can edit the ouputs/inputs added
So we have something like this:
I managed to build a dynamic canvas that changes when the user presses one of the buttons (the painted area grows).
The problem starts when the canvas is bigger than screen height. The result is something like this:
Notice that I have a scroll view. However it seems that scrollview puts everything in black. My xml file is something like this:
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<pt.mypackage.BlockCanvas
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<EditText
... />
<Button
... />
<Button
... />
</RelativeLayout>
</ScrollView>
I've experience something similar to your problem, I solved it by wrapping up the scroll view with RelativeLayout and using android:layout_allignParentTop="true". If doesnt work try adding empty view(no height just width) that will work as anchor to which your ScrollView will be placed below. I hope this makes sense and works