Developer
Developer

Reputation: 4331

Custom controls Android

I have passed few online courses on Android. And started my first project. Currently i'm stuck on creating my own Widget.

I cannot find any information on how to override default control styles or how to group default controls into custom control. The problem is:

When we create extend an Activity there is a method onCreated where we point which XML layout to use. In my opinion in the same way custom controls should be created.

For example, i want to create a control, that will have ImageView and some buttons, which type will depend on data coming from the server ( email button, skype button or any other )

So i created a class:

public class InteractiveHeaderControl extends View {

    public InteractiveHeaderControl(Context context)
    {
        super(context);
    }
}

I created a layout:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<ImageView
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content" 
    android:layout_centerVertical="true"
    android:text="TEST"
    android:layout_marginLeft="20dp"/>
<LinearLayout
    android:id="@+id/button_stack"
    android:layout_width="wrap_content"
    android:layout_height="50dp"
    android:orientation="horizontal"
    android:layout_alignParentBottom="true"
    android:layout_alignParentRight="true">

    <Button
        android:layout_width="50dp"
        android:layout_height="50dp" />
    <Button
        android:layout_width="50dp"
        android:layout_height="50dp" />
    <Button
        android:layout_width="50dp"
        android:layout_height="50dp" />
</LinearLayout>
</RelativeLayout>

So the question is, how can i apply this layout to my control and poulate the button_stack in runtime?

For example in code i want to create this control, like:

InteractiveHeaderControl control = new InteractiveHeaderControl(List<button>);

and in control constructor handle the passed parameter.

Upvotes: 0

Views: 178

Answers (2)

simekadam
simekadam

Reputation: 7384

There are many ways how to do it. For start read:

  1. How to create custom components
  2. How to create custom views in general

First, you should rather create a custom ViewGroup instead of a custom View. I advice not to pass the List of actuall view instances (in your case Buttons) through your constructor, but better to just pass some information (title, what to do after click,...) and then build your buttons in the component itself..

Upvotes: 1

Mikelis Kaneps
Mikelis Kaneps

Reputation: 4584

Use a Layout instead of a view. Here is a example:

public class DefaultHeading extends FrameLayout {        

    public DefaultHeading(Context context, AttributeSet attrs) {
        super(context, attrs);
        LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View view = mInflater.inflate(R.layout.default_heading, this, true);

        addView(view);
    }

And if you want to use some attributes:

Add this to res->values->attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="awesomeedit">
        <attr name="regex" format="string"/>
        <attr name="name" format="string"/>
        <attr name="hint" format="string"/>
        <attr name="error" format="string"/>
        <attr name="required" format="boolean"/>
        <attr name="link" format="string"/>
        <attr name="email" format="boolean"/>
        <attr name="number" format="boolean"/>
        <attr name="password" format="boolean"/>
    </declare-styleable>
</resources>

use it in your layout file:

<yourpackage.DefaultHeading
... 

android:layout_width="match_parent"
android:layout_height="wrap_content"
app:error="@string/not_valid_email_msg"
...
>

Get values:

 public class DefaultHeading extends FrameLayout {  



    public DefaultHeading(Context context, AttributeSet attrs) {
        super(context, attrs);


 TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.awesomeedit, 0, 0);
        String name;
        String regex;
        String hint;
        String error;
        String link;
        try {
            name = ta.getString(R.styleable.awesomeedit_name);
            regex = ta.getString(R.styleable.awesomeedit_regex);
            hint = ta.getString(R.styleable.awesomeedit_hint);
            error = ta.getString(R.styleable.awesomeedit_error);
            link = ta.getString(R.styleable.awesomeedit_link);
            required = ta.getBoolean(R.styleable.awesomeedit_required, false);
            email = ta.getBoolean(R.styleable.awesomeedit_email, false);
            password = ta.getBoolean(R.styleable.awesomeedit_password, false);
            nummber = ta.getBoolean(R.styleable.awesomeedit_number, false);
        } finally {
            ta.recycle();
        }
        LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View view = mInflater.inflate(R.layout.default_heading, this, true);

        addView(view);
    }

Upvotes: 1

Related Questions