김관덕 (새 블로그로 이전)

Toolbar (ActionBar) 번역 본문

Android/안드로이드 응용

Toolbar (ActionBar) 번역

Gwnduke's 2015. 11. 19. 14:46

[출처] http://www.vogella.com/tutorials/AndroidActionBar/article.html

안드로이드 툴바 (액션바) 사용하기 - 튜토리얼

Lars Vogel

Version 12

30.09.2015

Using the toolbar in Android applications

This tutorial describes how to use the toolbar widget in your Android application. It is based on Android 6.0.


목차

1. Introduction to the toolbar
1.1. What is the toolbar (action bar)?
1.2. Example
1.3. Action bar on devices lower than API 21
2. Using the toolbar
2.1. Entries in the action bar (actions)
2.2. Creating actions
2.3. Reacting to action selection
2.4. Search an action in the action bar
2.5. Changing the menu
3. Customizing the toolbar
3.1. Changing the visibility of the toolbar bar
3.2. Assigning a Drawable
3.3. Dimming the navigation buttons
3.4. Using immersive full screen mode
3.5. Enabling the split toolbar
4. Contributing to the action bar with fragments
5. Making the toolbar context sensitive with the contextual action mode
6. Exercise: Using the contextual action mode
6.1. Target
6.2. Create menu resource in the res/menu folder
6.3. Adjust your coding
7. Making the action bar dynamic
7.1. Custom views in the action bar
7.2. Action view
8. Action provider
8.1. What is an action provider?
8.2. Example: usage of the ShareActionProvider
9. Navigation via the application icon
9.1. Application icon as home
9.2. Application icon as Up button
10. Other means of actionbar navigation
10.1. Actionbar navigation is deprecated
10.2. Tab navigation
10.3. Dropdown menu navigation
10.4. Evaluation
11. Exercise: ActionBar
11.1. Project
12. Exercise: Add a toolbar to your application
12.1. Add a refresh icon
12.2. Add a menu XML resource
12.3. Add a toolbar view to your activity layout
12.4. Run the application and test the toolbar
13. References
13.1. Create an image via Android studio
13.2. Creating a resource file
13.3. Add a new menu XML resource
13.4. Remove the usage of the support library
14. About this website
15. Links and Literature
15.1. Android ActionBar Resources
15.2. vogella GmbH training and consulting support

1. 툴바 소개

1.1. 툴바(액션바)가 뭐죠?

툴바 (일반적으로 액션바라고 알려져있다) is represented as of Android 5.0 via the Toolbar view group 그리고 당신의 레이아웃 파일에 위치할 수있다. 툴바는 액티비티 제목, 아이콘, 트리거될 수 있는 액션들, 추가적인 뷰들, 그리고 다른 상호작용 아이템들을 보여줄 수 있다. 또한 어플리케이션의 네비게이션으로도 사용될 수 있다.

Android 5.0 이전에는 툴바의 위치가 액티비티의 상단에 하드코드되어 있었다.

The toolbar is enabled for devices which specify a target SDK of API version 11 or higher. 툴바는 used theme을 이용해 비활성화 할 수 있다. 그러나 안드로이드 themes는 툴바를 활성화 해놓았다.

Applications with a target SDK version less than API 11 use the options menu if such a button is present on the device. The option menu is displayed if the user presses the Option button. The toolbar bar is superior to the options menu, as the action bar is clearly visible, while the options menu is only shown on request. In case of the options menu, the user may not recognize that options are available in the application.

1.2. 예제

The following screenshot shows the toolbar of the Google+ Android application with interactive items and a navigation bar. On top it also indicates that the user can open a navigation bar on the side of the application.

ActionBar Screenshot

1.3. API 21 보다 낮은 디바이스에서 액션바 사용하기

The toolbar has been introduced in Android 5.0 (API 21). If you want to use the toolbar on devices with an earlier Android release you can use the downport provided by the appcompat-v7 support library. Add for this the latest version of com.android.support:appcompat to your Gradle build file, for example, at this pointcom.android.support:appcompat-v7:22.2.0. See the following link for setting up the library v7 in your project:Setting up the support library.

This section focuses on the description of using the toolbar bar without the support library. You can port your application to an lower API version using the support library.

2. 툴바 사용하기

2.1. Entries in the action bar (actions)

Entries in the toolbar are typically called actions. While it is possible to create entries in the action bar via code, it is typically defined in an XML resource file.

각 메뉴 정의는 res/menu 폴더의 분리된 파일에 포함되어 있다. Android tooling은 R 파일에 자동적으로 이 파일에 대한 참조를 생성한다. 그래서 메뉴 리소스에 접근가능하다.

2.2. 액션 만들기

An activity adds entries to the action bar in its onCreateOptionsMenu() method.

The showAsAction attribute allows you to define how the action is displayed. For example, the ifRoom attribute defines that the action is only displayed in the action bar if there is sufficient screen space available.

<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/action_refresh"
        android:orderInCategory="100"
        android:showAsAction="always"
        android:icon="@drawable/ic_action_refresh"
        android:title="Refresh"/>
    <item
        android:id="@+id/action_settings"
        android:title="Settings">
    </item>

</menu> 

 MenuInflator 클래스는 XML파일에 정의된 액션들을 inflate하고 액션바에 추가하도록 해준다. MenuInflator 는 액티비티의 getMenuInflator() 메소드를 통해 접근가능하다. 다음 예제 코드는 액션들의 생성을 보여줄 것이다.

@Override
  public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.mainmenu, menu);
    return true;
  } 

Tip

 

While you can define the actions also in your source code, it is good practice to do this via XML files, as this results in less boilerplate code. 

2.3. 액션 선택에 반응하기

액션바가 선택된다면, 그에 대응하는 액티비티의 onOptionsItemSelected() 메소드가 호출된다. 이것은 선택된 액션을 파라미터로서 받는다. 이 정보에 기초하여, 무엇을 할지 결정 할 수 있다. 이 메소드의 사용은 다음 코드 토막을 통해 보여줄 것이다.

@Override
  public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    // action with ID action_refresh was selected
    case R.id.action_refresh:
      Toast.makeText(this, "Refresh selected", Toast.LENGTH_SHORT)
          .show();
      break;
    // action with ID action_settings was selected
    case R.id.action_settings:
      Toast.makeText(this, "Settings selected", Toast.LENGTH_SHORT)
          .show();
      break;
    default:
      break;
    }

    return true;
  } 

2.4. 액션바에서 액션 찾기

메뉴에서 메뉴 아이템을 찾기위해서 Menu 클래스의 findItem() 메소드를 사용할 수 있다. 이 메소드는 id로 찾을 수 있도록 허용한다. 

2.5. 메뉴 변경하기

onCreateOptionsMenu() 메소는 딱 한번 호출된다. 만약 메뉴를 나중에 변경하길 원한다면, invalidateOptionsMenu() 메소드를 호출해야한다. 그 뒤에 onCreateOptionsMenu()  메소드가 다시 호출될 것이다.

3. 툴바 커스터마이징

3.1. 툴바의 visibility 변경

런타임에 툴바의 visibility 를 변경할 수 있다. 다음코드를 보자.

ActionBar actionBar = getActionBar();
actionBar.hide();
// more stuff here...
actionBar.show(); 

어플리케이션 아이콘과 나란히 있는 텍스트도 런타임에 변경 가능하다. 다음코드를 보자.

ActionBar actionBar = getActionBar();
actionBar.setSubtitle("mytest");
actionBar.setTitle("vogella.com"); 

3.2. Assigning a Drawable Drawable 배치하기?

You also add a Drawable to the action bar as background via the ActionBar.setBackgroundDrawable() method.

The toolbar scales the image. Therefore it is best practice to provide a scalable drawable , e.g., a 9-patch or XML drawable.

As of Android 4.2 the background of the action bar can also be animated via an AnimationDrawable.

3.3. Dimming the navigation buttons 흐리게 네비버튼

You can also dim the software navigation button in your Android application to have more space available. If the user touches the button of the screen, the navigation button is automatically shown again.

Dimming the navigation buttons is demonstrated by the following code snippet.

getWindow().
  getDecorView().
  setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); 

The following screenshots show an application with and without the navigation buttons.

Application with action bar

Application with dimmed action bar

3.4. Using immersive full screen mode

As of Android 4.4 (API 19) you can put your application into full screen mode. The first time this happens the system displays the user the info that he can restore the system bars with a downward swipe along the region where the system bars normally appear.

For example the following method also to put an activity into full screen mode.

// This method hides the system bars and resize the content
  private void hideSystemUI() {
    getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
            | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
            // remove the following flag for version < API 19
            | View.SYSTEM_UI_FLAG_IMMERSIVE); 
  } 

3.5. Enabling the split toolbar

You can define that the toolbar should be automatically split by the system if not enough space is available.

You can activate this via the android:uiOptions="SplitActionBarWhenNarrow" parameter in the declaration of your application activity in the AndroidManifest.xml file.

Note

 

If this option is activated, Android has the option to split the toolbar. Whether to split is decided by the system at runtime.

4. Contributing to the action bar with fragments

Fragments can also contribute entries to the toolbar bar.

To do this, call setHasOptionsMenu(true) in the onCreate() method of the fragment. The Android framework calls in this case the onCreateOptionsMenu() method in the fragment class and adds its menu items to the ones added by the activity .

5. Making the toolbar context sensitive with the contextual action mode

A contextual action mode activates a temporary toolbar that overlays the application toolbar for the duration of a particular sub-task.

The contextual action mode is typically activated by selecting an item or by long clicking on it.

To implement this, call the startActionMode() method on a view or on your activity. This method gets anActionMode.Callback object which is responsible for the life cycle of the contextual action bar.

You could also assign a context menu to a view via the registerForContextMenu(view) method. A context menu is also activated if the user "long presses" the view. The onCreateContextMenu() method is called every time a context menu is activated as the context menu is discarded after its usage. You should prefer the contextual action mode over the usage of context menus.

6. Exercise: Using the contextual action mode

6.1. Target

In this exercise you add a contextual action mode to one of your existing applications.

6.2. Create menu resource in the res/menu folder

For this, create a new menu XML resource with the actionmode.xml file name. See ??? for details.

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/action_share"
        android:title="Share it"
        >
    </item>
</menu> 

6.3. Adjust your coding

Extend your fragment interface.

public class MyListFragment extends Fragment {

    public void goToActionMode(RssItem item) {
        listener.goToActionMode(item);
    }

    public interface OnItemSelectedListener {

      public void onRssItemSelected(String link);

        public void goToActionMode(RssItem item);
    } 

Change your activity to implement this new method and also the ActionMode.Callback callback as demonstrated in the following example code.

package com.example.android.rssreader;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Toast;
import android.widget.Toolbar;

import com.example.android.rssfeedlibrary.RssItem;

public class RssfeedActivity extends Activity 
  implements MyListFragment.OnItemSelectedListener, 
        ActionMode.Callback {

    private RssItem selectedRssItem;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar tb = (Toolbar) findViewById(R.id.toolbar);
        setActionBar(tb);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        Toolbar tb = (Toolbar) findViewById(R.id.toolbar);
        tb.inflateMenu(R.menu.mainmenu);
        tb.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
                    @Override
                    public boolean onMenuItemClick(MenuItem item) {
                        return onOptionsItemSelected(item);
                    }
                });

        return true;
    }

    //NEW
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_refresh:
              MyListFragment fragment = (MyListFragment) getFragmentManager()
              .findFragmentById(R.id.listFragment);
              fragment.updateListContent();
                break;
            case R.id.action_settings:
                Intent intent = new Intent(this, MyPreferences.class);
                startActivity(intent);
                Toast.makeText(this, "Action Settings selected", Toast.LENGTH_SHORT)
                        .show();
                break;

            default:
                break;
        }

        return true;
    }


    @Override
    public void onRssItemSelected(String link) {
        if (getResources().getBoolean(R.bool.twoPaneMode)) {
            DetailFragment fragment = (DetailFragment) getFragmentManager()
                    .findFragmentById(R.id.detailFragment);
            fragment.setText(link);
        } else {
            Intent intent = new Intent(getApplicationContext(),
                    DetailActivity.class);
            intent.putExtra(DetailActivity.EXTRA_URL, link);
            startActivity(intent);
        }
    }

    @Override
    public void showContextMenu(RssItem item) {
        this.selectedRssItem = item;
        startActionMode(this);
    }

    @Override
    public void goToActionMode(RssItem item) {
        this.selectedRssItem = item;
        startActionMode(this);
    }


    @Override
    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
        MenuInflater inflater = mode.getMenuInflater();
        inflater.inflate(R.menu.actionmode, menu);
        return true;
    }

    @Override
    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
        return false;
    }

    @Override
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
        Intent intent = new Intent(Intent.ACTION_SEND);
        intent.putExtra(Intent.EXTRA_TEXT, "I found this interesting link" + 
            selectedRssItem.getLink());
        intent.setType("text/plain");
        startActivity(intent);
        mode.finish(); // Action picked, so close the CAB
        selectedRssItem = null;
        return true;
    }

    @Override
    public void onDestroyActionMode(ActionMode mode) {

    }
} 

In your adapter implement a LongClickListener which triggers the contextual action mode.

package com.example.android.rssreader;

import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.example.android.rssfeedlibrary.RssItem;

import java.util.List;
import java.util.Random;

public class RssItemAdapter
        extends RecyclerView.Adapter<RssItemAdapter.ViewHolder> {

    private List<RssItem> rssItems;
    private MyListFragment myListFragment;

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v= null;
        v = LayoutInflater.
                from(parent.getContext()).
                inflate(R.layout.rowlayout, parent, false);
        return new ViewHolder(v);
    }


    public static class ViewHolder extends RecyclerView.ViewHolder {
        public View mainLayout;
        public TextView txtHeader;
        public TextView txtFooter;
        public ImageView imageView;

        public ViewHolder(View v) {
            super(v);
            mainLayout = v;
            txtHeader = (TextView) v.findViewById(R.id.rsstitle);
            txtFooter = (TextView) v.findViewById(R.id.rssurl);
            imageView = (ImageView) v.findViewById(R.id.icon);
        }
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, final int position) {
        final RssItem rssItem = rssItems.get(position);
        holder.txtHeader.setText(rssItem.getTitle());
        holder.txtFooter.setText(rssItem.getLink());
        holder.mainLayout.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                myListFragment.updateDetail(rssItem.getLink());
            }
        });
        holder.mainLayout.setOnLongClickListener(new View.OnLongClickListener() {

            @Override
            public boolean onLongClick(View v) {
                myListFragment.goToActionMode(rssItem);
                return true;
            }

        });
    }

    @Override
    public int getItemCount() {
        return rssItems.size();
    }


    public RssItemAdapter(List<RssItem> rssItems, MyListFragment myListFragment) {
        this.rssItems = rssItems;
        this.myListFragment = myListFragment;
    }


} 

7. 액션바를 다이나믹하게 만들기

7.1. 액션바의 커스텀뷰

액션바에 버튼이나 텍스트필드 같은 커스텀뷰를 추가할 수 있다. ActionView 클래스의 setCustomView 메소드를 사용해라.  You also have to enable the display of custom views via the setDisplayOptions() method by passing in the ActionBar.DISPLAY_SHOW_CUSTOM flag.

예들들어, EditText 요소를 포함하는 레이아웃 파일을 정의할 수 있다.

<?xml version="1.0" encoding="utf-8"?>
<EditText xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/searchfield"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:inputType="textFilter" >

</EditText> 

This layout can be assigned in an activity to the action bar via the following code. The example code also attaches a listener to the custom view.

package com.vogella.android.actionbar.customviews;

import android.app.ActionBar;
import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import android.widget.Toast;

public class MainActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ActionBar actionBar = getActionBar();
    // add the custom view to the action bar
    actionBar.setCustomView(R.layout.actionbar_view);
    EditText search = (EditText) actionBar.getCustomView().findViewById(R.id.searchfield);
    search.setOnEditorActionListener(new OnEditorActionListener() {

      @Override
      public boolean onEditorAction(TextView v, int actionId,
          KeyEvent event) {
        Toast.makeText(MainActivity.this, "Search triggered",
            Toast.LENGTH_LONG).show();
        return false;
      }
    });
    actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM
        | ActionBar.DISPLAY_SHOW_HOME);
  }

} 

7.2. Action view

An action view is a widget that appears in the action bar as a substitute for an action item's button. You can, for example, use this feature to replace an action item with a ProgressBar view. An action view for an action can be defined via the android:actionLayout or android:actionViewClass attribute to specify either a layout resource or widget class to use.

This replacement is depicted in the following screenshots.

Before activating the ActionView

ActionViews running

The following activity replaces the icon at runtime with an action view which contains a ProgressBar view.

package com.vogella.android.actionbar.progress;

import android.app.ActionBar;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends Activity {

  private MenuItem menuItem;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ActionBar actionBar = getActionBar();
    actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME
        | ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_CUSTOM);
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.menu_load:
      menuItem = item;
      menuItem.setActionView(R.layout.progressbar);
      menuItem.expandActionView();
      TestTask task = new TestTask();
      task.execute("test");
      break;
    default:
      break;
    }
    return true;
  }

  private class TestTask extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... params) {
      // Simulate something long running
      try {
        Thread.sleep(2000);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      return null;
    }

    @Override
    protected void onPostExecute(String result) {
      menuItem.collapseActionView();
      menuItem.setActionView(null);
    }
  };
} 

The following code shows the layout used for the action view.

<?xml version="1.0" encoding="utf-8"?>
<ProgressBar xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/progressBar2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

</ProgressBar> 

The following code shows the XML files for the menu.

<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/menu_settings"
        android:orderInCategory="100"
        android:showAsAction="always"
        android:title="Settings"
        />

    <item
        android:id="@+id/menu_load"
        android:icon="@drawable/navigation_refresh"
        android:orderInCategory="200"
        android:showAsAction="always"
        android:title="Load"/>

</menu> 

8. Action provider

8.1. What is an action provider?

An action provider defines rich menu interaction in a single component. It can generate action views, which are used in the action bar, dynamically populate sub-menus of an action and handle default action invocations.

The base class for an action provider is the ActionProvider class.

Currently the Android platform provides two action providers: the MediaRouteActionProvider and theShareActionProvider.

8.2. Example: usage of the ShareActionProvider

The following demonstrates the usage of the ShareActionProvider. This action provider allows you to grab selected content from applications which have registered the Intent.ACTION_SEND intent.

To use ShareActionProvider, you have to define a special menu entry for it and assign an intent which contains the sharing data to it.

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

   <item android:id="@+id/menu_share"
          android:title="Share"
          android:showAsAction="ifRoom"
          android:actionProviderClass="android.widget.ShareActionProvider" />
    <item
        android:id="@+id/item1"
        android:showAsAction="ifRoom"
        android:title="More entries...">
    </item>

</menu> 

@Override
  public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_main, menu);

    // Get the ActionProvider for later usage
    provider = (ShareActionProvider) menu.findItem(R.id.menu_share)
        .getActionProvider();
    return true;
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.menu_share:
      doShare();
      break;
    default:
      break;
    }
    return true;  
  }

  public void doShare() {
    // populate the share intent with data
    Intent intent = new Intent(Intent.ACTION_SEND);
    intent.setType("text/plain");
    intent.putExtra(Intent.EXTRA_TEXT, "This is a message for you");
    provider.setShareIntent(intent);
  } 

9. Navigation via the application icon

9.1. Application icon as home

The action bar shows an icon of your application. This is called the home icon. You can assign an action to this icon. The recommendation is to return to the main activity in your program if the user selects this icon.

If the action is selected, the onOptionsItemSelected() method is called with an action which has theandroid.R.id.home ID.

Before Android 4.1, you had to use the android.R.id.home ID in the onOptionMenuItemSelected() method and enable the selection of the home button. This is demonstrated by the following code in which the SecondActivityactivity defines the MainActivity as home.

package com.vogella.android.actionbar.homebutton;

import android.os.Bundle;
import android.app.ActionBar;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.MenuItem;

public class SecondActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // enable the home button
    ActionBar actionBar = getActionBar();
    actionBar.setHomeButtonEnabled(true);
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case android.R.id.home:
      Intent intent = new Intent(this, MainActivity.class);
      intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
      startActivity(intent);
      break;
      // Something else
    case R.id.action_settings:
      intent = new Intent(this, ThirdActivity.class);
      startActivity(intent);
    default:
      break;
    }
    return super.onOptionsItemSelected(item);
  }

} 

Tip

 

As of Android 4.1 you can simply set the parentActivityName in the AndroidManifest.xml file pointing to the parent activity.

<activity
  android:name="SecondActivity"
  android:label="@string/app_name"
  android:parentActivityName="MainActivity" >
</activity> 

9.2. Application icon as Up button

You can use the application icon also as Up button, e.g., to go to the parent activity of the current activity. The back button on the device always returns to the previous activity.

Both can be different, for example, if the user started the option to write an email from the home screen, the back button will return the user to the home screen while the Up button would return the user to the activity which shows an overview of all emails.

To enable the Up display, you can use the following code snippet in your activity.

actionBar.setDisplayUseLogoEnabled(false);
actionBar.setDisplayHomeAsUpEnabled(true); 

Note

 

This snippet only enables the Up display on your home icon. You need to implement the correct behavior in your activity in the onOptionsItemSelected() method. The corresponding action still has the android.R.id.home ID.

Warning

 

The difference between Up and the Back button can be confusing for the end user. If you decide to implement Up, in your application, it is recommended to perform some end user testing to see if the Up implementation is intuitive for them or not.

10. 액션바 네비게이션의 다른 방법들(수단들)

10.1. Actionbar 네비게이션은 deprecated 되었다.

As of Android 5.0 the navigation options described in this chapter are deprecated and should not be used anymore in new applications.

10.2. Tab 네비게이션

Fragments can also be used in combination with the action bar for navigation. 이를 위해서 메인 엑티비티는 탭간 이동에 책임을 지는 TabListener 를 implement해야한다.

액션바에 새로운 탭을 추가하기 위해서,  newTab() 메서드를 사용하라.

다음 코드들은 such an activity를 보여준다. 이것은 더미 액티비티를 사용한다 스위치를 보여주기 위해.

package com.vogella.android.actionbar.tabs;

import android.app.ActionBar;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class MainActivity extends FragmentActivity implements
    ActionBar.TabListener {

  
/** * The serialization (saved instance state) Bundle key representing the * current tab position. */
private static final String STATE_SELECTED_NAVIGATION_ITEM = "selected_navigation_item"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Set up the action bar to show tabs. final ActionBar actionBar = getActionBar(); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); // for each of the sections in the app, add a tab to the action bar. actionBar.addTab(actionBar.newTab().setText(R.string.title_section1) .setTabListener(this)); actionBar.addTab(actionBar.newTab().setText(R.string.title_section2) .setTabListener(this)); actionBar.addTab(actionBar.newTab().setText(R.string.title_section3) .setTabListener(this)); } @Override public void onRestoreInstanceState(Bundle savedInstanceState) { // Restore the previously serialized current tab position. if (savedInstanceState.containsKey(STATE_SELECTED_NAVIGATION_ITEM)) { getActionBar().setSelectedNavigationItem(savedInstanceState.getInt(STATE_SELECTED_NAVIGATION_ITEM)); } } @Override public void onSaveInstanceState(Bundle outState) { // Serialize the current tab position. outState.putInt(STATE_SELECTED_NAVIGATION_ITEM, getActionBar() .getSelectedNavigationIndex()); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; } @Override public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { // When the given tab is selected, show the tab contents in the // container view. Fragment fragment = new DummySectionFragment(); Bundle args = new Bundle(); args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, tab.getPosition() + 1); fragment.setArguments(args); getFragmentManager().beginTransaction() .replace(R.id.container, fragment).commit(); } @Override public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { } @Override public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { }
/** * A dummy fragment representing a section of the app */
public static class DummySectionFragment extends Fragment { public static final String ARG_SECTION_NUMBER = "placeholder_text"; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { TextView textView = new TextView(getActivity()); textView.setGravity(Gravity.CENTER); textView.setText(Integer.toString(getArguments().getInt(ARG_SECTION_NUMBER))); return textView; } } }

10.3. Dropdown menu 네비게이션

implementation. 당신은 또한 액션바에서 스피너를 이용할 수 있다. 다음 코드들은 such an implementation을 보여준다.

package com.vogella.android.actionbar.spinner;

import android.app.ActionBar;
import android.app.Fragment;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

public class MainActivity extends FragmentActivity implements
    ActionBar.OnNavigationListener {

  
/** * The serialization (saved instance state) Bundle key representing the * current dropdown position. */
private static final String STATE_SELECTED_NAVIGATION_ITEM = "selected_navigation_item"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Set up the action bar to show a dropdown list. final ActionBar actionBar = getActionBar(); actionBar.setDisplayShowTitleEnabled(false); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); final String[] dropdownValues = getResources().getStringArray(R.array.dropdown); // Specify a SpinnerAdapter to populate the dropdown list. ArrayAdapter<String> adapter = new ArrayAdapter<String>(actionBar.getThemedContext(), android.R.layout.simple_spinner_item, android.R.id.text1, dropdownValues); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); // Set up the dropdown list navigation in the action bar. actionBar.setListNavigationCallbacks(adapter, this); // use getActionBar().getThemedContext() to ensure // that the text color is always appropriate for the action bar // background rather than the activity background. } @Override public void onRestoreInstanceState(Bundle savedInstanceState) { // Restore the previously serialized current dropdown position. if (savedInstanceState.containsKey(STATE_SELECTED_NAVIGATION_ITEM)) { getActionBar(). setSelectedNavigationItem(savedInstanceState.getInt(STATE_SELECTED_NAVIGATION_ITEM)); } } @Override public void onSaveInstanceState(Bundle outState) { // Serialize the current dropdown position. outState.putInt(STATE_SELECTED_NAVIGATION_ITEM, getActionBar() .getSelectedNavigationIndex()); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; } @Override public boolean onNavigationItemSelected(int position, long id) { // When the given dropdown item is selected, show its contents in the // container view. Fragment fragment = new DummySectionFragment(); Bundle args = new Bundle(); args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, position + 1); fragment.setArguments(args); getFragmentManager().beginTransaction() .replace(R.id.container, fragment).commit(); return true; }
/** * A dummy fragment */
public static class DummySectionFragment extends Fragment { public static final String ARG_SECTION_NUMBER = "placeholder_text"; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { TextView textView = new TextView(getActivity()); textView.setGravity(Gravity.CENTER); textView.setText(Integer.toString(getArguments().getInt(ARG_SECTION_NUMBER))); return textView; } } }

10.4. 평가

navigation drawer 는 다른 옵션들에 비해 상대적으로  새로운 것인데 반해 사용자들과 안드로이드 어플리케이션 사이에서 꽤나 대중적이다. 만약 어떤 옵션을 선택해야할지 의심이 든다면 navigation drawer를 사용하는 것을 고려해보라.

11. Exercise: ActionBar

11.1. 프로젝트

이 챕터는 어떻게 액션들을 액션바에 만드는지와 어떻게 사용자의 선택에 반응하는지를 보여줄것이다.

이 것은 fragment 튜토리얼( Android fragments tutorial. )에 기반하고 있다. 만약 당신이 이미 이 프로젝트를 만들었다면, 당신은 계속해서 그것을 재사용할 수 있다. 다음은 이 튜토리얼을 계속하기 위해 필요한 사항들을 설명한다.

12. Exercise: Add a toolbar to your application

12.1. Add a refresh icon

Continue to use the RSS Reader project. Create a new icon called ic_refresh. See Section 13.1, “Create an image via Android studio” for details how to create an image.

12.2. Add a menu XML resource

Create a new XML resource for your menu called mainmenu.xml. See ??? for details how to do it.

Add two entries so that the resulting XML file, similar to the following listing. You may have to type these entries, as the time of this writing Android Studio offers no code completion of menus.

<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/action_refresh"
        android:orderInCategory="100"
        android:showAsAction="ifRoom"
        android:icon="@drawable/ic_action_refresh"
        android:title="Refresh"/>
    <item
        android:id="@+id/action_settings"
        android:title="Settings"
        android:showAsAction="never"
        >
    </item>

</menu> 

12.3. Add a toolbar view to your activity layout

Change the layout file of your RssfeedActivity activity to also contain a toolbar entry.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical">
    
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:orientation="horizontal"
        android:layout_weight="1"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        >

        <fragment
            android:id="@+id/listFragment"
            class="com.example.android.rssreader.MyListFragment"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            tools:layout="@layout/fragment_rsslist_overview"></fragment>

        <fragment
            android:id="@+id/detailFragment"
            class="com.example.android.rssreader.DetailFragment"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="2"
            tools:layout="@layout/fragment_rssitem_detail" />

    </LinearLayout>

    <Toolbar
        android:id="@+id/toolbar"
        style="@style/ToolbarStyling"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentStart="true">

    </Toolbar>
</LinearLayout> 

Change your RssfeedActivity class to the following code, to configure the toolbar view.

package com.example.android.rssreader;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

public class RssfeedActivity extends Activity implements MyListFragment.OnItemSelectedListener {
  // Unchanged
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_rssfeed);
    Toolbar tb = (Toolbar) findViewById(R.id.toolbar);
      // ensure toolbar acts as action bar
    setActionBar(tb);
  }
  
  //New
  @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        Toolbar tb = (Toolbar) findViewById(R.id.toolbar);
        tb.inflateMenu(R.menu.mainmenu);
        tb.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
                    @Override
                    public boolean onMenuItemClick(MenuItem item) {
                        return onOptionsItemSelected(item);
                    }
                });
        return true;
    }
  
  //New
  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.action_refresh:
      Toast.makeText(this, "Action refresh selected", Toast.LENGTH_SHORT)
          .show();
      break;
    case R.id.action_settings:
      Toast.makeText(this, "Action Settings selected", Toast.LENGTH_SHORT)
          .show();
      break;

    default:
      break;
    }

    return true;
  }

  // Other methods which this class implements
} 

12.4. Run the application and test the toolbar

Run your application and validate that you can select both of your actions. Ensure that the correct info message is displayed if you select the different entries.

Social App running

If your device or emulator has an Option menu button, you will not see the overflow menu. Press the Option key to see your second action.

13. References

13.1. Create an image via Android studio

See Creating an image asset to learn how to create an image asset with Android Studio.

13.2. Creating a resource file

See Creating a new resource file to learn how to a new resource file with Android Studio.

13.3. Add a new menu XML resource

See Add a new menu XML resource to learn how to a new XML menu resource with Android Studio.

13.4. Remove the usage of the support library

See Android support library how to remove the usage of the support library.

15. Links and Literature

15.1. Android ActionBar Resources

Android Design Page

Android ActionBar Sherlock

15.2. vogella GmbH training and consulting support

TRAININGSERVICE & SUPPORT
The vogella company provides comprehensivetraining and education services from experts in the areas of Eclipse RCP, Android, Git, Java, Gradle and Spring. We offer both public and inhouse training. Whichever course you decide to take, you are guaranteed to experience what many before you refer to as “The best IT class I have ever attended”.The vogella company offers expert consultingservices, development support and coaching. Our customers range from Fortune 100 corporations to individual developers.


'Android > 안드로이드 응용' 카테고리의 다른 글

안드로이드 참고 사이트  (0) 2015.12.20
이벤트 처리에서의 final 선언 @Android  (0) 2015.10.08
LayoutInflater  (0) 2015.10.08
findViewById  (0) 2015.10.08