Im kind of new to Android.
I am playing around with the Android FingerPaint API Sample. I have figured out how to add buttons and functions to the Menu, but how do I get buttons on the actual screen?
Is it possible to place buttons over the drawing surface? Or would I need a linear (Vertical) layout on the left, and place buttons in there. Either would be fine.
Help? Thanks.
The Android FingerPaint sample code does not use a layout; it instead just has a subclass of View called MyView, and then the Activity sets its content view to be an instance of MyView.
If you want to have more than one View on the screen, you'll need to use some sort of layout. You could use a LinearLayout if you want the MyView for painting to be above, below, or to the side of the buttons; if you want the buttons to be on top of the MyView, take a look at using a FrameLayout or RelativeLayout.
You can either then define the layout in XML or create it manually in code. The former is more flexible and maintainable, but there will be a few hiccups.
First, create a layout XML showing how you want your components to be laid out. For this example, we'll call it finger_paint.xml. Make sure you have a MyView in there somewhere, something like:
<view class="com.example.android.apis.graphics.FingerPaint$MyView"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
Then, replace the line that looks like
setContentView(new MyView(this));
with
setContentView(R.layout.finger_paint);
Note that because MyView does not (yet) have the proper constructor for being instantiated by the LayoutInflater, this will not work yet, so let's fix that. Add an additional import near the top of the file:
import android.util.AttributeSet;
and then add an AttributeSet parameter to the constructor of MyView:
public MyView(Context c, AttributeSet as) {
super(c, as);
// rest of constructor is same as in the sample
}
You will also have to change MyView to be a static inner class of FingerPaint.
You may find the Building Custom Components document and the NotePad sample useful as you figure this out.
Good luck!
Are you trying to dynamically position your buttons?
If so, you can use setLayoutParams to set the layout properties of the button.
Related
I'm new to Android and have recently started adopting the pattern to create an auto-layout-loading custom view based on a layout file. In the layout you use the 'merge' tag as the root, then in the constructor of your view, you inflate that layout into yourself so you are essentially the root of the merged-in controls. Right after you inflate, still in the constructor, you can find the child controls from the layout and assign them to private fields in the custom class so they will always be available, even when using recycler views.
Contrast that with including a layout. In that case, the layout has to define a root element (which can be your custom control, but in that case, you would not inflate the layout into yourself and would have to move the control lookup to onFinishInflate) but otherwise it ends up with the same view hierarchy.
In short, instead of this...
<include layout="#layout/layout_myCustomControl" />
You can now do this...
<com.mydomain.MyCustomControl />
However I find the auto-loading custom control version to be much more flexible and maintainable. The advantages of the second one are not only that you can use custom attributes in the referencing XML layouts (which you can't with the 'include' version) but it also gives you a central place to manage the code as well as layout management/control lookup.
So now I can do this...
<com.mydomain.MyCustomControl
app:myCustomAttribute="Foo" />
And if the control has to have code backing up its behavior, it's nicely encapsulated in the custom view.
Here's an example layout for the auto-loading version...
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This is static text in the header" />
<TextView android:id="#+id/dateTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</merge>
And here's the class that uses it...
public class MainHeader extends LinearLayout
{
TextView dateTextView;
public MainHeader(Context context, #Nullable AttributeSet attrs)
{
super(context, attrs);
setOrientation(VERTICAL);
LayoutInflater.from(context).inflate(R.layout.header_main, this);
dateTextView = (TextView)findViewById(R.id.dateTextView);
dateTextView.setText(<<Code for setting date goes here>>);
}
}
But what I'm wondering is if the layout is purely static in nature--say holding a static image and fixed text--is it still considered good practice to use a custom view to represent it? I'd say yes for consistency, plus should I want to extend it in the future, you're already prepared for it and have to do so in just one place regardless of how many places it's used. In contrast, if you included the layout directly in say 20 places, you may have to update all 20 (depending on what's actually changed/needed.)
Pros for the Custom View approach:
Central location for managing layout loading and control lookup
Can support backing code implicitly/internally for updating the view.
Can use attributes when being referenced in other layout files
Better encapsulation (you can hide the layout itself from the outside world exposing behaviors via direct methods)
Can simply be 'new'd' up in code and the layout will automatically load. No inflating or casting needed.
Cons for Custom View approach
When used in Layout files, you now have to also specify width and height making usage a little more verbose.
May add extra classes to your project (not always, but sometimes.)
Again, it seems to me like a no-brainer, but I'm wondering if there's a preferred 'Androidy' way, or is it just a preference up to each developer?
Such approach will add additional level in your view trees. So you only made the UI tree more complex for no good reason. From other side, you can follow next steps to get rid of that side-effect:
<merge /> can only be used as the root tag of an XML layout
when inflating a layout starting with a <merge />, you must specify a parent
ViewGroup and you must set attachToRoot to true (see the
documentation of the inflate() method)
That's it.
Well apparently what I came up with wasn't that unique after all! Here's an article explaining in detail this exact scenario, along with the pros and cons of each. Looks like they too came to the same conclusion.
TrickyAndroid: Protip. Inflating layout for your custom view
I want to create zig-zag layout same as following attached image:
I tried a lot by creating diagonal lines and arranging them with icon but couldn't make it same.
I implemented diagonal lines with the help of accepted answer from following questions:
Diagonal line across view
How rotate line in Android XML?
However I'm stuck to arrange lines with icons exactly same as in image.
I created this custom ZigZagLayout.java file to cater your requirement. You just have to update the package name in the 1st line.
It basically extends RelativeLayout, so you can use it in your layout-xmls just like any other ViewGroup class. Once you have instantiated this layout, just add child-views to it like it is done for RelativeLayout via addView(View child).
Example code snippet with dynamically created view:
ZigZagLayout zigZagLayout = (ZigZagLayout) findViewById(R.id.layout_zigzag);
Button btn = new Button(this);
btn.setText("Test Button");
btn.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT));
zigZagLayout.addView(btn);
I've also added few interfaces to this ZigZagLayout for your easy interaction like ability to set the connector-line stroke width, visibility, color, margins, etc.
Try it out and let me know if it suffices your requirement. Cheers.
If you have layout for each circular item , you may use relative layout to align them, using align_below, align_left with margin, align_right with margin tags.
Please provide further detail, what are the lines connecting them and exactly what all are requirements for UI and functionality.
Regarding this example -
http://android-coding.blogspot.com/2011/05/detect-multi-touch-event-test-on-custom.html
How can I add EditText to the view ?
I tried to add it to the layout but when I'm trying to update it I'm getting error message.
Thanks
I found a nice example here - http://www.kellbot.com/2009/06/android-hello-circle.
I added EditText to the layout and its working fine.
In order to use this example the code should be written as explained in Sebastien's comment, in which he uses parent as described in this line:
final Activity parent = this;
The MultiTouchView from the link extends a View. You cannot add other Views to a View. You will need the MultiTouchView to extend a ViewGroup. See the android doc on building custom components.
To be able to add views, I think replacing the following line in the sample code
public class MultiTouchView extends View {
with
public class MultiTouchView extends FrameLayout {
should work because FrameLayout is a subclass of ViewGroup. You may want to chose a different layout depending on your needs.
How to enbbed a GraphicsView into a layout? Or how do I add buttons and textViews to a GraphicsView? Could some one post a simple working example?
-Henry
I don't think you can add other Views inside a View component.
GraphicsView is not a default Android SDK class, so we can't know what you have there, sorry.
Make a Layout component to be able to add View components inside it.
To embed your GraphicsView in a layout in xml use something like:
<com.package.GraphicsView
id="#+id/graphics"
...
/>
I have a small xml file called 'xmlview.xml' which is something like:
<tablelayout>
<tablerow>
<view id="view1" />
I created a class which extends view, and I inflated that xml file and now i have a view obtained due to inflation.
xmlView = layoutInflater.inflate(R.layout.xmlview, this);
I am wondering is there a way to draw on the view 'view1' inside the view 'xmlview'
I tried something like:
View view1 = (View)xmlview.findById(R.Id.view1);
and then I tried in the overriden onDraw to draw on view1 but nothing worked,
any ideas ??
Seems to me maybe you should try something like this:
<TableLayout>
<TableRow>
<com.yourdomain.yourproject.ViewClassName>
Then you can create a class ViewClassName that extends View and, on that class, override the onDraw method. This is explained in detail here: http://developer.android.com/guide/topics/ui/custom-components.html. You can go directly the topic Modifying an Existing View Type
See, you don't need to inflate the view if the only reason to do this is to try and manipulate the view's drawing. And if it is the only reason, you really shouldn't.
hope I helped
I'm not sure what exactly you mean by "draw on the view", but it sounds like you should be looking into the Canvas. You should not arbitrarily override the onDraw method, this is what causes your widgets to appear on the screen.