Friday, December 20, 2013

ActionBarCompat with ShareActionProvider to update dynamic content

Last exercise "ActionBarCompat with ShareActionProvider" setup share content in onCreateOptionsMenu(). The share data will not be updated after then. In this exercise, ShareIntent will be updated when user update content.

In my experiment, onOptionsItemSelected() will not be called when Share menu item clicked. So a TextWatcher is implemented when any EditText changed, to update ShareIntent.

ActionBarCompat with ShareActionProvider to update dynamic content
ActionBarCompat with ShareActionProvider to update dynamic content
Modify layout to add EditTexts for user to enter email address, title and content.
<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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:autoLink="web"
        android:text="http://android-er.blogspot.com/"
        android:textStyle="bold" />
    
    <EditText 
        android:id="@+id/fieldemailaddress"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="textEmailAddress"
        android:hint="email address" />
    <EditText 
        android:id="@+id/fieldemailtitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Hello from android-er.blogspot.com" 
        android:hint="email title"/>
    <EditText 
        android:id="@+id/fieldemailcontent"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" 
        android:hint="email content"/>

</LinearLayout>

/res/menu/main.xml, same as before.
<menu 
    xmlns:myapp="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android" >

 <item
        android:id="@+id/action_share"
        android:title="Share"
        myapp:actionProviderClass="android.support.v7.widget.ShareActionProvider"
        myapp:showAsAction="always|withText" />
    <item
        android:id="@+id/action_settings"
        myapp:showAsAction="always|withText"
        android:title="@string/action_settings"/>

</menu>

MainActivity.java
package com.example.testactionbarcompat;

import android.content.Intent;
import android.os.Bundle;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.ShareActionProvider;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends ActionBarActivity {
 
 EditText fieldEmailAddress, fieldEmailTitle, fieldEmailContent;
 
 private ShareActionProvider myShareActionProvider;

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

        setContentView(R.layout.activity_main);
        fieldEmailAddress = (EditText)findViewById(R.id.fieldemailaddress);
        fieldEmailTitle = (EditText)findViewById(R.id.fieldemailtitle);
        fieldEmailContent = (EditText)findViewById(R.id.fieldemailcontent);
        
        fieldEmailAddress.addTextChangedListener(myTextWatcher);
        fieldEmailTitle.addTextChangedListener(myTextWatcher);
        fieldEmailContent.addTextChangedListener(myTextWatcher);
    }

    /*
     * update ActionProvider by calling setShareIntent()
     * When any EditText changed
     */
    TextWatcher myTextWatcher = new TextWatcher(){

  @Override
  public void afterTextChanged(Editable s) {
   setShareIntent();
  }

  @Override
  public void beforeTextChanged(CharSequence s, int start, 
    int count, int after) {}

  @Override
  public void onTextChanged(CharSequence s, int start, 
    int before, int count) {}
 };

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        
        //add MenuItem(s) to ActionBar using Java code
        MenuItem menuItem_Info = menu.add(0, R.id.menuid_info, 0, "Info");
        menuItem_Info.setIcon(android.R.drawable.ic_menu_info_details);
        MenuItemCompat.setShowAsAction(menuItem_Info, 
          MenuItem.SHOW_AS_ACTION_ALWAYS|MenuItem.SHOW_AS_ACTION_WITH_TEXT);
        
        //Handle share menu item
        MenuItem shareItem = menu.findItem(R.id.action_share);
        myShareActionProvider = (ShareActionProvider)
          MenuItemCompat.getActionProvider(shareItem);
        setShareIntent();
        
        //return true;
        return super.onCreateOptionsMenu(menu);
    }

 @Override
 public boolean onOptionsItemSelected(MenuItem item) {
  // TODO Auto-generated method stub
  //return super.onOptionsItemSelected(item);
  switch (item.getItemId()) {
  case R.id.action_share: 
   //It never called in my experiment
   Toast.makeText(this, "Share", Toast.LENGTH_SHORT).show();
   setShareIntent();
   return false;
        case R.id.action_settings: 
         //match with /res/menu/main.xml
            Toast.makeText(this, "Setting", Toast.LENGTH_SHORT).show();
            return true;
        case R.id.menuid_info:  
         //match with defined in onCreateOptionsMenu()
         Toast.makeText(this, "Info", Toast.LENGTH_SHORT).show();
            return true;
        default:
            return super.onOptionsItemSelected(item);    
  }
 }
    
 //Set the share intent
 private void setShareIntent(){
  
  Intent intent = new Intent(Intent.ACTION_SEND);
  intent.setType("plain/text");
  intent.putExtra(Intent.EXTRA_EMAIL, 
    new String[]{fieldEmailAddress.getText().toString()}); 
  intent.putExtra(Intent.EXTRA_SUBJECT, 
    fieldEmailTitle.getText().toString());
  intent.putExtra(Intent.EXTRA_TEXT, 
    fieldEmailContent.getText().toString()); 

  myShareActionProvider.setShareIntent(intent); 
 }

}


download filesDownload the files.



Visit: ActionBarCompat Step-by-step

No comments: