2016年4月18日 星期一

Using the App ToolBar

ref http://guides.codepath.com/android/Using-the-App-ToolBar#overview

Using the App ToolBar

Overview

ToolBar was introduced in Android Lollipop, API 21 release and is the spiritual successor of the ActionBar. It's a ViewGroupthat can be placed anywhere in your XML layouts. ToolBar's appearance and behavior can be more easily customized than the ActionBar.
ToolBar works well with apps targeted to API 21 and above. However, Android has updated the AppCompat support libraries so the ToolBar can be used on lower Android OS devices as well. In AppCompat, ToolBar is implemented in theandroid.support.v7.widget.Toolbar class.
There are two ways to use Toolbar:
  1. Use a Toolbar as an Action Bar when you want to use the existing ActionBar facilities (such as menu inflation and selection, ActionBarDrawerToggle, and so on) but want to have more control over its appearance.
  2. Use a standalone Toolbar when you want to use the pattern in your app for situations that an Action Bar would not support; for example, showing multiple toolbars on the screen, spanning only part of the width, and so on.

ToolBar vs ActionBar

The ToolBar is a generalization of the ActionBar system. The key differences that distinguish the ToolBar from the ActionBarinclude:
  • ToolBar is a View included in a layout like any other View
  • As a regular View, the toolbar is easier to position, animate and control
  • Multiple distinct ToolBar elements can be defined within a single activity
Keep in mind that you can also configure any ToolBar as an Activity’s ActionBar, meaning that your standard options menu actions will be display within.
Note that the ActionBar continues to work and if all you need is a static bar at the top that can host icons and a back button, then you can safely continue to use ActionBar.

Using ToolBar as ActionBar

To use Toolbar as an ActionBar, first ensure the AppCompat-v7 support library is added to your application build.gradle(Module:app) file:
dependencies {
  ...
  compile 'com.android.support:appcompat-v7:23.1.0'
}
Second, let's disable the theme-provided ActionBar. The easiest way is to have your theme extend fromTheme.AppCompat.NoActionBar (or the light variant) within the res/styles.xml file:
<resources>
  <!-- Base application theme. -->
  <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
  </style>
</resources>
Now you need to add a Toolbar to your Activity layout file. One of the biggest advantages of using the Toolbar widget is that you can place the view anywhere within your layout. Below we place the toolbar at the top of a LinearLayout like the standard ActionBar:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar
      android:id="@+id/toolbar"
      android:minHeight="?attr/actionBarSize"  
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      app:titleTextColor="@android:color/white"
      android:background="?attr/colorPrimary">
    </android.support.v7.widget.Toolbar>

    <!-- Layout for content is here. This can be a RelativeLayout  -->

</LinearLayout>
As Toolbar is just a ViewGroup and can be styled and positioned like any other view. Note that this means if you are in aRelativeLayout, you need to ensure that all other views are positioned below the toolbar explicitly. The toolbar is not given any special treatment as a view.
Next, in your Activity or Fragment, set the Toolbar to act as the ActionBar by calling the setSupportActionBar(Toolbar)method:
Note: When using the support library, make sure that you are importing android.support.v7.widget.Toolbar and notandroid.widget.Toolbar.
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;

public class MyActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);

        // Find the toolbar view inside the activity layout
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        // Sets the Toolbar to act as the ActionBar for this Activity window.
        // Make sure the toolbar exists in the activity and is not null
        setSupportActionBar(toolbar);
    }

    // Menu icons are inflated just as they were with actionbar
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }
}
Next, we need to make sure we have the action items listed within a menu resource file such as res/menu/menu_main.xmlwhich is inflated above in onCreateOptionsMenu:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/miCompose"
        android:icon="@drawable/ic_compose"
        app:showAsAction="ifRoom"
        android:title="Compose">
    </item>
    <item
        android:id="@+id/miProfile"
        android:icon="@drawable/ic_profile"
        app:showAsAction="ifRoom|withText"
        android:title="Profile">
    </item>
</menu>
For more details about action items in the Toolbar including how to setup click handling, refer to our ActionBar guide. The above code results in the toolbar fully replacing the ActionBar at the top:
From this point on, all menu items are displayed in your Toolbar, populated via the standard options menu callbacks.

Reusing the Toolbar

In many apps, the same toolbar can be used across multiple activities or in alternative layout resources for the same activity. In order to easily reuse the toolbar, we can leverage the layout include tag as follows. First, define your toolbar in a layout file in res/layout/toolbar_main.xml:
<android.support.v7.widget.Toolbar
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?attr/colorPrimary"/>
Next, we can use the <include /> tag to load the toolbar into our activity layout XML:
<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:orientation="vertical">

    <!-- Load the toolbar here -->
    <include
        layout="@layout/toolbar_main"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/> 

    <!-- Rest of content for the activity -->

</LinearLayout>
This allows us to create a consistent navigation experience across activities or configuration changes.

Styling the Toolbar

The Toolbar can be customized in many ways leveraging various style properties including android:theme,app:titleTextAppearanceapp:popupTheme. Each of these can be mapped to a style. Start with:
<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:minHeight="?attr/actionBarSize"  
    android:theme="@style/ToolbarTheme"
    app:titleTextAppearance="@style/Toolbar.TitleText"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
/>
Now, we need to create the custom styles in res/styles.xml with:
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
  <!-- Customize your theme here. -->
  <item name="colorPrimary">@color/colorPrimary</item>
  <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
  <item name="colorAccent">@color/colorAccent</item>
</style>

<style name="ToolbarTheme" parent="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
  <!-- This would set the toolbar's background color -->
  <item name="android:background">@color/colorPrimary</item>
  <!-- android:textColorPrimary is the color of the title text in the Toolbar  -->
  <item name="android:textColorPrimary">@android:color/holo_blue_light</item>
  <!-- android:actionMenuTextColor is the color of the text of action (menu) items  -->
  <item name="actionMenuTextColor">@android:color/holo_green_light</item>
  <!-- Enable these below if you want clicking icons to trigger a ripple effect -->
  <!-- 
  <item name="selectableItemBackground">?android:selectableItemBackground</item>
  <item name="selectableItemBackgroundBorderless">?android:selectableItemBackground</item> 
  -->
</style>

<!-- This configures the styles for the title within the Toolbar  -->
<style name="Toolbar.TitleText" parent="TextAppearance.Widget.AppCompat.Toolbar.Title">
    <item name="android:textSize">21sp</item>
    <item name="android:textStyle">italic</item>
</style>
This results in:

Displaying an App Icon

In certain situations, we might want to display an app icon within the Toolbar. This can be done by adding this code into theActivity
// Find the toolbar view and set as ActionBar
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// ...
// Display icon in the toolbar
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setLogo(R.mipmap.ic_launcher);
getSupportActionBar().setDisplayUseLogoEnabled(true);
Next, we need to remove the left inset margin that pushes the icon over too far to the left by adding app:contentInsetStart to the Toolbar:
<android.support.v7.widget.Toolbar
      android:id="@+id/toolbar"
      app:contentInsetLeft="0dp"
      app:contentInsetStart="0dp"
      ...
      >
</android.support.v7.widget.Toolbar>
With that the icon should properly display within the ToolBar as expected.

Custom Title View

Toolbar is just a decorated ViewGroup and as a result, the title contained within can be completely customized by embedding a view within the Toolbar such as:
<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar"
    android:minHeight="?attr/actionBarSize"  
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:titleTextColor="@android:color/white"
    android:background="?attr/colorPrimary">

     <TextView
        android:id="@+id/toolbar_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Toolbar Title"
        android:textColor="@android:color/white"
        style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"
        android:layout_gravity="center"
     />

</android.support.v7.widget.Toolbar>
This means that you can style the TextView like any other. You can access the TextView inside your activity with:
/* Inside the activity */
// Sets the Toolbar to act as the ActionBar for this Activity window.
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Remove default title text
getSupportActionBar().setDisplayShowTitleEnabled(false);
// Get access to the custom title view
TextView mTitle = (TextView) toolbar.findViewById(R.id.toolbar_title);
Note that you must hide the default title using setDisplayShowTitleEnabled. This results in:

2016年3月22日 星期二

How to Create GCE Module(Make your own API)

ref:
https://github.com/GoogleCloudPlatform/gradle-appengine-templates/tree/master/HelloEndpoints

see the above link,you can learn how to create a api on google cloud,and use in android.

below example show how to add you self method.

public class MyEndpoint {
    private static int jokeAcount = 0;
    final String[] jokeArray = {"joke1", "joke2", "joke3", "joke4", "joke5"};

    /**
     * A simple endpoint method that takes a name and says Hi back
     */
    @ApiMethod(name = "sayHi2")
    public MyBean sayHi2(@Named("name") String name) {
        MyBean response = new MyBean();
        response.setData("Hi, " + name);

        return response;
    }

    @ApiMethod(name = "getJoke")
    public JokeObject getJoke() {
        JokeObject jokeObject = new JokeObject(jokeArray[jokeAcount]);
        jokeAcount++;
        if (jokeAcount >= jokeArray.length) jokeAcount = 0;

        return jokeObject;
    }

}

2016年3月9日 星期三

How to partially update the widget

ref:http://stackoverflow.com/questions/11808331/how-to-partially-update-views-in-an-app-widget-without-rebuilding-all-the-remote



can use in onReceive.

PendingIntent.getBroadcast request code,problem

PendingIntent leftpendingIntent = PendingIntent.getBroadcast(context, request code, leftintent, 0);

if for the intent,has the same action,and same request code,android system may thaink that the Broadcast is the same and send the old Brodcast,although the putExtra method,put other thing.

List view in Widget:when data changed,show the update data in list view

use : https://github.com/roy989898/Advanced_Android_Development/tree/7.04_Integrating_the_Detail_Widget

be a example



step 1: register the provide with one more action 


<receiver
            android:name=".widget.DetailWidgetProvider"
            android:label="@string/title_widget_detail"
            android:enabled="@bool/widget_detail_enabled" >
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
                <action android:name="com.example.android.sunshine.app.ACTION_DATA_UPDATED" />
            </intent-filter>
            <meta-data android:name="android.appwidget.provider"
                android:resource="@xml/widget_info_detail" />
        </receiver>

step2 in DetailWidgetProvider overview onReceive


@Override
    public void onReceive(@NonNull Context context, @NonNull Intent intent) {
        super.onReceive(context, intent);
        if (SunshineSyncAdapter.ACTION_DATA_UPDATED.equals(intent.getAction())) {
            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
            int[] appWidgetIds = appWidgetManager.getAppWidgetIds(
                    new ComponentName(context, getClass()));
            appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.widget_list);
        }
    }

the above code  will call the RemoteViewsFactory 's onDataSetChanged method.

step 3 override the onDataSetChanged  in RemoteViewsFactory class

if (data != null) {
                    data.close();
                }
                // This method is called by the app hosting the widget (e.g., the launcher)
                // However, our ContentProvider is not exported so it doesn't have access to the
                // data. Therefore we need to clear (and finally restore) the calling identity so
                // that calls use our process and permission
                final long identityToken = Binder.clearCallingIdentity();
                String location = Utility.getPreferredLocation(DetailWidgetRemoteViewsService.this);
                Uri weatherForLocationUri = WeatherContract.WeatherEntry
                        .buildWeatherLocationWithStartDate(location, System.currentTimeMillis());
                data = getContentResolver().query(weatherForLocationUri,
                        FORECAST_COLUMNS,
                        null,
                        null,
                        WeatherContract.WeatherEntry.COLUMN_DATE + " ASC");
                Binder.restoreCallingIdentity(identityToken);


explain

data = getContentResolver().query(weatherForLocationUri,
                        FORECAST_COLUMNS,
                        null,
                        null,
                        WeatherContract.WeatherEntry.COLUMN_DATE + " ASC");

use to get the data again.


step 4 send the broadcast with action define in step 1 to update



2016年3月2日 星期三

send Broadcast and Broadcast Receiver

Broadcast Receiver

1.create a class extends Brodcast Receiver

2. override onReceive
this method will run after the Receiver receive the brodcast

 private class MyBrodcastReceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
//do something
        }
    }

3 register the Broadcast Receiver
only registered Broadcast Receiver can receiver brodcast,what message ,depend on the intern filter

M1.register in the program


//register the brodcast receiver
                MyBrodcastReceiver mybrodcastReceiver=new MyBrodcastReceiver();
                IntentFilter intentFilter=new IntentFilter(BRODCAST_ACTION);
                getActivity().registerReceiver(mybrodcastReceiver,intentFilter);


M2.register in XML

 <receiver android:name=".AddBook$MyBrodcastReceiver">
            <intent-filter>
                <action android:name="it.jaschke.alexandria.brodcastmessage"/>
            </intent-filter>
        </receiver>



4.send Brodcast

Intent brodcastIntent=new Intent();
    brodcastIntent.setAction(AddBook.BRODCAST_ACTION);
    sendBroadcast(brodcastIntent);

the action should be match to the InterFilter.

How to check the connection state:

How to check the connection state:


1.get the permission:
<!--Permission to check the connection state-->
   <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

2.get the ConnectivityManager
Context.getSystemService(Context.CONNECTIVITY_SERVICE).

3.check
ConnectivityManager cm =
       (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork != null &&
                     activeNetwork.isConnectedOrConnecting();