Views, or as some one calls them Rich Views, are simple tool for working with one activity lifecycle. They are light weight and can take care for most of the work, not bothering with the activity livecycle, because the Views, or Rich Views are binded with the activity livecycle scope, or simply as long as the activity is alive, the view is also alive.
But here comes the next obvious question: Why just not use Fragments instead? Well here comes the deal, Fragments have theyr own livecycle with 12 methods that we need to overwrite, and with view we need to care about only one thing, the inflatement of the layout of the View, and thats it. Fragments are used, and were more fancy, with the tablets, wich have much more unused display space, to fill with separate functionalities like camera fragment split vertically and GPS fragment wit inner fragment map. But all of that is heavy lifting behind the screens, worrying about life-cycles of all fragments called. As is mentioned before, Views comes for the rescue. Simple, lightweight and functional. Imagine Views as layers above the Activity, and as far the Activity is alive, the Views are alive too, they are like headless activities.
In the next code example we will see how to implement several Rich Views.
NOTE:
I’m using ButterKnife library for binding the buttons, texts, edit texts, and ect
NOTE:
In this example we use Navigation Drawer, so I can visually represent the functionality of the Rich Views. This Navigation Drawer was explained in one of my previous blog posts.
NOTE:
They are all VIEWS, but im am referring as Reach Views in our example so I can distinct them from the other Views, like Text View, and something like that.
After the Navigation Drawer implementation, we must declare where to handle the Rich View chooser, as navigation drawer items:
HomeActivity.java
The magic happens in onNavigationSelected(), or in another words, when we click on an item on the navigation drawer menu, correct Reach View appears on the screen.
The Views are initialized in the container that we import in our layout for the HomeActivity which is match_parent for width and height. We pass the container new object from our Rich View class, witch have inflater implemented in the View constructor, so the View is displayed when the Rich View object is created. The container is declared as Frame Layout, to hold our Rich View.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
public class HomeActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { @BindView(R.id.nav_view) NavigationView navigationView; @BindView(R.id.toolbar) Toolbar toolbar; @BindView(R.id.container) FrameLayout container; @BindView(R.id.drawer_layout) DrawerLayout drawer; private int navItemIndex = 1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_home); ButterKnife.bind(this); setupUi(); } private void setupUi() { setSupportActionBar(toolbar); ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); drawer.addDrawerListener(toggle); toggle.syncState(); navigationView.setNavigationItemSelectedListener(this); container.addView(new FirstView(this)); } @Override public void onBackPressed() { if (drawer.isDrawerOpen(GravityCompat.START)) { drawer.closeDrawer(GravityCompat.START); } else { super.onBackPressed(); } } @Override public boolean onNavigationItemSelected(MenuItem item) { container.removeAllViews(); int id = item.getItemId(); switch (id) { case R.id.firstView: navItemIndex = 0; container.addView(new FirstView(this)); break; case R.id.secondView: container.addView(new SecondView(this)); navItemIndex = 1; break; case R.id.thirdView: container.addView(new ThirdView(this)); navItemIndex = 2; break; case R.id.fourthView: container.addView(new FourthView(this)); navItemIndex = 3; break; case R.id.fifthView: container.addView(new FifthView(this)); navItemIndex = 4; break; case R.id.sixthView: container.addView(new SixthView(this)); navItemIndex = 5; break; case R.id.seventhView: container.addView(new SeventhView(this)); navItemIndex = 6; break; default: navItemIndex = 0; } drawer.closeDrawer(GravityCompat.START); return true; } }<span data-mce-type="bookmark" id="mce_SELREST_start" data-mce-style="overflow:hidden;line-height:0" style="overflow:hidden;line-height:0" ></span> |
Here is the XML code for the HomeActivity layout, and only element that we care about for now is the FrameLayout declared with id as container. That container is initialized in our HomeActivity:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/firstView" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/firstText" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="@string/first_view" android:textAllCaps="true" android:textColor="@color/colorBlack" android:textSize="20sp" /> </RelativeLayout> |
Here is our second Reach View with some buttons inside:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
public class SecondView extends RelativeLayout { @OnClick(R.id.firstButton) public void onClickFirstButton(){ Toast.makeText(getContext(), "Button clicked", Toast.LENGTH_SHORT).show(); } @OnClick(R.id.secondButton) public void onClickSecondButton(){ Toast.makeText(getContext(), "Button clicked", Toast.LENGTH_SHORT).show(); } public SecondView(Context context) { super(context); init(); } private void init() { inflate(getContext(), R.layout.view_second, this); ButterKnife.bind(this); } } |
… and the layout code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/secondView" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/secondText" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="@string/second_view" android:textAllCaps="true" android:textColor="@color/colorBlack" android:textSize="20sp" /> <RelativeLayout android:id="@+id/buttonContainer" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/secondText" android:layout_centerHorizontal="true" android:layout_marginEnd="50dp" android:layout_marginStart="50dp" android:layout_marginTop="20dp"> <Button android:id="@+id/firstButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:text="button" /> <Button android:id="@+id/secondButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:text="button" /> </RelativeLayout> </RelativeLayout> |
NOTE:
When we use Rich Views, this cannot be applyed because is activity special command, but we can use getContext() method, which takes the context from the activity which the Rich View is called.