Skip to content

Instantly share code, notes, and snippets.

@OrenBochman
Last active September 9, 2018 10:32
Show Gist options
  • Save OrenBochman/7ed363866a3e9ef892ec8a78434198db to your computer and use it in GitHub Desktop.
Save OrenBochman/7ed363866a3e9ef892ec8a78434198db to your computer and use it in GitHub Desktop.
Determine the Current Layout in Android

Activity that adapts

To develop great UI the designer impliments different layouts for different breakpoints.

Two Layout

  • orientation:vertical (1st break point) - master_frag and detail_frag are each in a FragmentActiity
  • orientation:horizontal (2nd break point) - master_detail_act.xml incorprating master_frag and detail_frag fragments
  1. Detection is done in onCreate is testing for the articleView View in the detail fragment. if it is available we are in master/detail layout.
  • This is stored in mIsDualPane
  1. Add a listener - only if the button is available (due to layout or due to API version)

  2. We can use the onHeadlineSelected to implemet different behavior based on mIsDualPane ** if dual - update the fragment. ** if not - start an intent.

  3. set the actionbar ** if dual - use tabs for navigation ** if not - use spinner

  4. reuse of fragment in XML within in a layout

  5. and again via code in a FragmentActivity

  6. using an interface to decouple activity and fragment

  7. the fragment then uses the inerface to access the activity.

  8. reacting to config change from single page detail to two pane master/detail.

  9. using a strategy pattern to further simplify the handling different breakponits/layouts c.f. https://developer.android.com/training/multiscreen/adaptui

/**
* use a boolean var mIsDualPane - in the controller logic based on a view's visibility
*/
public class AdaptiveDualPaneActivity extends FragmentActivity {
boolean mIsDualPane; //the state
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
//detect articleView
View articleView = findViewById(R.id.article);
mIsDualPane = articleView != null && articleView.getVisibility() == View.VISIBLE;
this.listenIfExists();
}
}
/**
* only hook up the button listner if the button has been found.
*/
public void listenIfExists(){
Button catButton = (Button) findViewById(R.id.categorybutton);
OnClickListener listener = /* create your listener here */;
if (catButton != null) {
catButton.setOnClickListener(listener);
}
}
/**
* this is a simple way to handle controller logic based on mIsDualPane
*
*/
@Override
public void onHeadlineSelected(int index) {
mArtIndex = index;
if (mIsDualPane) {
/* display article on the right pane */
mArticleFragment.displayArticle(mCurrentCat.getArticle(index));
} else {
/* start a separate activity */
Intent intent = new Intent(this, ArticleActivity.class);
intent.putExtra("catIndex", mCatIndex);
intent.putExtra("artIndex", index);
startActivity(intent);
}
}
final String CATEGORIES[] = { "Top Stories", "Politics", "Economy", "Technology" };
public void onCreate(Bundle savedInstanceState) {
....
if (mIsDualPane) {
/* use tabs for navigation */
actionBar.setNavigationMode(android.app.ActionBar.NAVIGATION_MODE_TABS);
int i;
for (i = 0; i < CATEGORIES.length; i++) {
actionBar.addTab(actionBar.newTab().setText(
CATEGORIES[i]).setTabListener(handler));
}
actionBar.setSelectedNavigationItem(selTab);
}
else {
/* use list navigation (spinner) */
actionBar.setNavigationMode(android.app.ActionBar.NAVIGATION_MODE_LIST);
SpinnerAdapter adap = new ArrayAdapter<String>(this,
R.layout.headline_item, CATEGORIES);
actionBar.setListNavigationCallbacks(adap, handler);
}
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<fragment android:id="@+id/headlines"
android:layout_height="fill_parent"
android:name="com.example.android.newsreader.HeadlinesFragment"
android:layout_width="400dp"
android:layout_marginRight="10dp"/>
<fragment android:id="@+id/article"
android:layout_height="fill_parent"
android:name="com.example.android.newsreader.ArticleFragment"
android:layout_width="fill_parent" />
</LinearLayout>
//reusing this without a layout
getSupportFragmentManager().beginTransaction()
.add(android.R.id.content, new ArticleFragment())
.commit();
public class HeadlinesFragment extends ListFragment {
...
OnHeadlineSelectedListener mHeadlineSelectedListener = null;
/* Must be implemented by host activity */
public interface OnHeadlineSelectedListener {
public void onHeadlineSelected(int index);
}
...
public void setOnHeadlineSelectedListener(OnHeadlineSelectedListener listener) {
mHeadlineSelectedListener = listener;
}
}
public class HeadlinesFragment extends ListFragment {
...
public void onItemClick(AdapterView<?> parent,
View view, int position, long id) {
if (null != mHeadlineSelectedListener) {
mHeadlineSelectedListener.onHeadlineSelected(position);
}
}
...
}
public class ArticleActivity extends FragmentActivity {
int mCatIndex, mArtIndex;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mCatIndex = getIntent().getExtras().getInt("catIndex", 0);
mArtIndex = getIntent().getExtras().getInt("artIndex", 0);
// If should be in two-pane mode, finish to return to main activity
if (getResources().getBoolean(R.bool.has_two_panes)) {
finish();
return;
}
...
}
public interface Strategy {
String reportWeather();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment