Legacy of screens - Android

Asked

Viewed 1,383 times

6

Wanted to create a screen(Activity) base for the android app I’m developing, so that all other screens inherited from this base. Thus, the screen would have an area reserved for the top of the page, a central region where the content will be variable and a footer area that would contain two buttons.
How could I do that?

  • 2

    I think the idea would be to make use of Fragment in the area that is variable. But implementation details for this I do not have. I personally avoid using them.

  • 1

    As @mutlei said Fragments is the best solution. I see no reason not to use them. For a better understanding, I recommend taking a look at this question: http://answall.com/questions/17483/qual-a-diferent%C3%A7a-entre-desenhar-na-Activity-e-no-Fragment/17502#17502.

  • I avoid using them because the applications I’ve made so far, @Wakim, didn’t need them and just gave me more headache. But if used well, they can be a hand on the wheel, I believe.

3 answers

8


Other answers have already given some alternatives, but I think I can add one more.

My suggestion would be to create a layout unique as being a template and use a real ViewStub to define the dynamic content of this template during the creation of Activity's.

For example:

xml template.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="5dp">

    <!-- Aqui entra seu topo -->
    <include ... />

    <!-- O ViewStub guarda lugar para um layout
         a ser definido por quem usar -->
    <ViewStub android:id="@+id/stub"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:weight="1" />

    <!-- Aqui entra seu fundo -->
    <include ... />
</LinearLayout>

To dynamically change the layout during the creation of Activity just do:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Pode "setar" normalmente seu layout
    setContentView(R.layout.template);

    ViewStub vs = findViewById(R.id.stub);

    // Define qual o layout a ser inflado
    vs.setLayoutResource(R.layout.seuLayoutAtual);
    View conteudoPrincipal = vs.inflate();
}

Recalling that the ViewStub will leave the tree and will give way to every subtree that is defined in the layout you pass in the method ViewStub.setLayoutResource. The method inflate returns the root layout you inflated.

That way you reuse the same layout just changing the content you need.


For the question of function/behaviour belonging to the template, you can create a class, can be abstract if you prefer, that inherits from some subclass or own Activity (FragmentActivity, ListActivity and so on) to contain this behavior that is common to all.

You’d have something like:

public abstract class BaseActivity extends Activity {

    // Template method para retornar o conteudo
    // interno ao template.
    // Sendo abstrato para obrigar que a subclass forneca
    public abstract @LayoutRes int getContentLayoutId();

    // Metodo responsavel por configurar o conteudo do template
    public abstract void onCreateContent(View conteudo);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.template);

        ViewStub vs = findViewById(R.id.stub);

        // Define qual o layout a ser inflado
        vs.setLayoutResource(getContentLayoutId());
        View conteudoPrincipal = vs.inflate();

        // Configuracao de listener de eventos e etc

        // Deixa a subclasse configurar o conteudo
        onCreateContent(conteudoPrincipal);
    }

    // Metodos comuns
}

Where each Activity that will use the template define the content:

public class ActivityLoja extends BaseActivity {
    @Override
    public int getContentLayoutId() {
        return R.layout.loja;
    }

    @Override
    public void onCreateContent(View conteudo) {
        // Configuracao do conteudo
    }

    // Restante do codigo da sua Activity
}

public class ActivityCarrinho extends BaseActivity {
    @Override
    public int getContentLayoutId() {
        return R.layout.carrinho;
    }

    @Override
    public void onCreateContent(View conteudo) {
        // Configuracao do conteudo
    }

    // Restante do codigo da sua Activity
}

The record is normal, as if there was no inheritance:

<activity
    android:name=".activity.ActivityLoja"
    android:label="@string/loja" />

<activity
    android:name=".activity.ActivityCarrinho"
    android:name="@string/carrinho" />

Some references:

  • that is undoubtedly the best, least laborious and most organized way to carry out this work!

  • In case I want to create a "complete" Activity as a basis, that is, to have methods implemented in the class related to the xml components, would have to make the inheritance of that too?

  • Oh yes, it is possible and quite common. You can have an abstract class (abstract or not, depending on your modeling) that has all the methods in common. She must inherit from Activity or ActionBarActivity or another subclass of Activity. All the others Activity's who use the template can inherit from this common class which is also a Activity valid.

  • In the code of the abstract class, where we have vs.setLayoutResource(getContentResId()); actually is: vs.setLayoutResource(getContentLayoutId()); correct?

  • This @Murilofechio, my mistake, I will correct, otherwise it is correct.

  • Very good his solution, had already used the inheritance of Activity, but the idea of the template is genius!!!

Show 1 more comment

5

I believe you want to be a Screen Designer(XML) and not Screen(Activity) I’m right?

If that is your question then, you want to know how to do an old practice of reuse of layouts as well as good practice on web pages.

To make a screen or an xml layout that can be reused everywhere from the app, so it has a top one body and a footer.

do..

master_top.xml

<?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"
android:background="#ffffff"
android:padding="5dp" >

<ImageView
    android:id="@+id/imageView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true"
    android:layout_margin="5dp"
    android:src="@drawable/my_logo" />

</RelativeLayout>

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#f0f0f0" >


<include android:id="@+id/topo_view"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    layout="@layout/master_top" />

<LinearLayout
    android:id="@+id/linearLayout1"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_margin="10dp"
    android:background="#ffffff"
    android:orientation="vertical"
    android:padding="5dp" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="$$$$$$$ CORPO $$$$$$$"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:textColor="#1AA52F" />

</LinearLayout>

<include
    android:id="@+id/rodape_view"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    layout="@layout/master_footer" />

</RelativeLayout>

master_footer.xml

<?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"
android:background="#ffffff"
android:padding="5dp" >

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:gravity="center"
    android:text="-----------RODAPE---------------"
    android:textColor="#EFEFEF" />

</RelativeLayout>

...

You can also use < merge >

REF official website. http://developer.android.com/training/improving-layouts/reusing-layouts.html

  • In this case, in all the screens that I draw I would have to do the top include, the footer and create a layout for the center, correct? There would be no way I could give the include in an xml type this activity_main that you gave of example and "draw" only the contents of the interior of Linearlayout?

4

Have it so, it would be like you do the opposite of example! In the example is just make a copy of (XML) and change the body and ready. But there is no escape, a part of the layout you will not get out of the work of doing.

To do this way you spoke just do the opposite.

Example:

activity_main.xml

<?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"
    android:background="#ffffff"
    android:padding="5dp" >

    <!-- Top -->
    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_margin="5dp"
        android:src="@drawable/my_logo" />



<!-- Body -->
    <include android:id="@+id/topo_view"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        layout="@layout/my_body" />



    <!-- Footer --> 
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:gravity="center"
        android:text="-----------RODAPE---------------"
        android:textColor="#EFEFEF" />

    </RelativeLayout>

my_body.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:background="#f0f0f0" >


    <LinearLayout
        android:id="@+id/linearLayout1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:background="#ffffff"
        android:orientation="vertical"
        android:padding="5dp" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@@@@@@@ MY BODY @@@@@@@@"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:textColor="#1AA52F" />

    </LinearLayout>


    </RelativeLayout>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.