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:
I think the idea would be to make use of
Fragmentin the area that is variable. But implementation details for this I do not have. I personally avoid using them.– mutlei
As @mutlei said
Fragmentsis 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.– Wakim
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.
– mutlei