Add browseable samples for L SDK release
Change-Id: I71c6ff9a90b7734042d68af7f01e6d61118cc508
This commit is contained in:
@@ -0,0 +1,244 @@
|
||||
/*
|
||||
* Copyright 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.interpolator;
|
||||
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.graphics.Path;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.view.animation.Interpolator;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.example.android.common.logger.Log;
|
||||
|
||||
/**
|
||||
* This sample demonstrates the use of animation interpolators and path animations for
|
||||
* Material Design.
|
||||
* It shows how an {@link android.animation.ObjectAnimator} is used to animate two properties of a
|
||||
* view (scale X and Y) along a path.
|
||||
*/
|
||||
public class InterpolatorFragment extends Fragment {
|
||||
|
||||
/**
|
||||
* View that is animated.
|
||||
*/
|
||||
private View mView;
|
||||
/**
|
||||
* Spinner for selection of interpolator.
|
||||
*/
|
||||
private Spinner mInterpolatorSpinner;
|
||||
/**
|
||||
* SeekBar for selection of duration of animation.
|
||||
*/
|
||||
private SeekBar mDurationSeekbar;
|
||||
/**
|
||||
* TextView that shows animation selected in SeekBar.
|
||||
*/
|
||||
private TextView mDurationLabel;
|
||||
|
||||
/**
|
||||
* Interpolators used for animation.
|
||||
*/
|
||||
private Interpolator mInterpolators[];
|
||||
/**
|
||||
* Path for in (shrinking) animation, from 100% scale to 20%.
|
||||
*/
|
||||
private Path mPathIn;
|
||||
/**
|
||||
* Path for out (growing) animation, from 20% to 100%.
|
||||
*/
|
||||
private Path mPathOut;
|
||||
|
||||
/**
|
||||
* Set to true if View is animated out (is shrunk).
|
||||
*/
|
||||
private boolean mIsOut = false;
|
||||
|
||||
/**
|
||||
* Default duration of animation in ms.
|
||||
*/
|
||||
private static final int INITIAL_DURATION_MS = 750;
|
||||
|
||||
/**
|
||||
* String used for logging.
|
||||
*/
|
||||
public static final String TAG = "InterpolatorplaygroundFragment";
|
||||
|
||||
public InterpolatorFragment() {
|
||||
// Required empty public constructor
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
|
||||
// Inflate the fragment_animation layout
|
||||
View v = inflater.inflate(R.layout.interpolator_fragment, container, false);
|
||||
|
||||
// Set up the 'animate' button, when it is clicked the view is animated with the options
|
||||
// selected: the Interpolator, duration and animation path
|
||||
Button button = (Button) v.findViewById(R.id.animateButton);
|
||||
button.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
// Interpolator selected in the spinner
|
||||
Interpolator interpolator = mInterpolators[mInterpolatorSpinner.getSelectedItemPosition()];
|
||||
// Duration selected in SeekBar
|
||||
long duration = mDurationSeekbar.getProgress();
|
||||
// Animation path is based on whether animating in or out
|
||||
Path path = mIsOut ? mPathIn : mPathOut;
|
||||
|
||||
// Log animation details
|
||||
Log.i(TAG, String.format("Starting animation: [%d ms, %s, %s]",
|
||||
duration, (String) mInterpolatorSpinner.getSelectedItem(),
|
||||
((mIsOut) ? "Out (growing)" : "In (shrinking)")));
|
||||
|
||||
// Start the animation with the selected options
|
||||
startAnimation(interpolator, duration, path);
|
||||
|
||||
// Toggle direction of animation (path)
|
||||
mIsOut = !mIsOut;
|
||||
}
|
||||
});
|
||||
|
||||
// Get the label to display the selected duration
|
||||
mDurationLabel = (TextView) v.findViewById(R.id.durationLabel);
|
||||
|
||||
// Initialize Interpolators programmatically by loading them from their XML definitions
|
||||
// provided by the framework.
|
||||
mInterpolators = new Interpolator[]{
|
||||
new AnimationUtils().loadInterpolator(getActivity(),
|
||||
android.R.interpolator.linear),
|
||||
new AnimationUtils().loadInterpolator(getActivity(),
|
||||
android.R.interpolator.fast_out_linear_in),
|
||||
new AnimationUtils().loadInterpolator(getActivity(),
|
||||
android.R.interpolator.fast_out_slow_in),
|
||||
new AnimationUtils().loadInterpolator(getActivity(),
|
||||
android.R.interpolator.linear_out_slow_in)
|
||||
};
|
||||
|
||||
// Load names of interpolators from a resource
|
||||
String[] interpolatorNames = getResources().getStringArray(R.array.interpolator_names);
|
||||
|
||||
// Set up the Spinner with the names of interpolators
|
||||
mInterpolatorSpinner = (Spinner) v.findViewById(R.id.interpolatorSpinner);
|
||||
ArrayAdapter<String> spinnerAdapter =
|
||||
new ArrayAdapter<String>(getActivity(),
|
||||
android.R.layout.simple_spinner_dropdown_item, interpolatorNames);
|
||||
mInterpolatorSpinner.setAdapter(spinnerAdapter);
|
||||
|
||||
// Set up SeekBar that defines the duration of the animation
|
||||
mDurationSeekbar = (SeekBar) v.findViewById(R.id.durationSeek);
|
||||
|
||||
// Register listener to update the text label when the SeekBar value is updated
|
||||
mDurationSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
|
||||
mDurationLabel.setText(getResources().getString(R.string.animation_duration, i));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
}
|
||||
});
|
||||
|
||||
// Set initial progress to trigger SeekBarChangeListener and update UI
|
||||
mDurationSeekbar.setProgress(INITIAL_DURATION_MS);
|
||||
|
||||
// Get the view that will be animated
|
||||
mView = v.findViewById(R.id.square);
|
||||
|
||||
// The following Path definitions are used by the ObjectAnimator to scale the view.
|
||||
|
||||
// Path for 'in' animation: growing from 20% to 100%
|
||||
mPathIn = new Path();
|
||||
mPathIn.moveTo(0.2f, 0.2f);
|
||||
mPathIn.lineTo(1f, 1f);
|
||||
|
||||
// Path for 'out' animation: shrinking from 100% to 20%
|
||||
mPathOut = new Path();
|
||||
mPathOut.moveTo(1f, 1f);
|
||||
mPathOut.lineTo(0.2f, 0.2f);
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start an animation on the sample view.
|
||||
* The view is animated using an {@link android.animation.ObjectAnimator} on the
|
||||
* {@link View#SCALE_X} and {@link View#SCALE_Y} properties, with its animation based on a path.
|
||||
* The only two paths defined here ({@link #mPathIn} and {@link #mPathOut}) scale the view
|
||||
* uniformly.
|
||||
*
|
||||
* @param interpolator The interpolator to use for the animation.
|
||||
* @param duration Duration of the animation in ms.
|
||||
* @param path Path of the animation
|
||||
* @return The ObjectAnimator used for this animation
|
||||
* @see android.animation.ObjectAnimator#ofFloat(Object, String, String, android.graphics.Path)
|
||||
*/
|
||||
public ObjectAnimator startAnimation(Interpolator interpolator, long duration, Path path) {
|
||||
// This ObjectAnimator uses the path to change the x and y scale of the mView object.
|
||||
ObjectAnimator animator = ObjectAnimator.ofFloat(mView, View.SCALE_X, View.SCALE_Y, path);
|
||||
|
||||
// Set the duration and interpolator for this animation
|
||||
animator.setDuration(duration);
|
||||
animator.setInterpolator(interpolator);
|
||||
|
||||
animator.start();
|
||||
|
||||
return animator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the array of loaded Interpolators available in this Fragment.
|
||||
*
|
||||
* @return Interpolators
|
||||
*/
|
||||
public Interpolator[] getInterpolators() {
|
||||
return mInterpolators;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the animation path for the 'in' (shrinking) animation.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Path getPathIn() {
|
||||
return mPathIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the animation path for the 'out' (growing) animation.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Path getPathOut() {
|
||||
return mPathOut;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright 2013 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.interpolator;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.ViewAnimator;
|
||||
|
||||
import com.example.android.common.activities.SampleActivityBase;
|
||||
import com.example.android.common.logger.Log;
|
||||
import com.example.android.common.logger.LogFragment;
|
||||
import com.example.android.common.logger.LogWrapper;
|
||||
import com.example.android.common.logger.MessageOnlyLogFilter;
|
||||
|
||||
/**
|
||||
* A simple launcher activity containing a summary sample description, sample log and a custom
|
||||
* {@link android.support.v4.app.Fragment} which can display a view.
|
||||
* <p>
|
||||
* For devices with displays with a width of 720dp or greater, the sample log is always visible,
|
||||
* on other devices it's visibility is controlled by an item on the Action Bar.
|
||||
*/
|
||||
public class MainActivity extends SampleActivityBase {
|
||||
|
||||
public static final String TAG = "MainActivity";
|
||||
|
||||
// Whether the Log Fragment is currently shown
|
||||
private boolean mLogShown;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
|
||||
InterpolatorFragment fragment = new InterpolatorFragment();
|
||||
transaction.replace(R.id.sample_content_fragment, fragment);
|
||||
transaction.commit();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.main, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
MenuItem logToggle = menu.findItem(R.id.menu_toggle_log);
|
||||
logToggle.setVisible(findViewById(R.id.sample_output) instanceof ViewAnimator);
|
||||
logToggle.setTitle(mLogShown ? R.string.sample_hide_log : R.string.sample_show_log);
|
||||
|
||||
return super.onPrepareOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch(item.getItemId()) {
|
||||
case R.id.menu_toggle_log:
|
||||
mLogShown = !mLogShown;
|
||||
ViewAnimator output = (ViewAnimator) findViewById(R.id.sample_output);
|
||||
if (mLogShown) {
|
||||
output.setDisplayedChild(1);
|
||||
} else {
|
||||
output.setDisplayedChild(0);
|
||||
}
|
||||
supportInvalidateOptionsMenu();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
/** Create a chain of targets that will receive log data */
|
||||
@Override
|
||||
public void initializeLogging() {
|
||||
// Wraps Android's native log framework.
|
||||
LogWrapper logWrapper = new LogWrapper();
|
||||
// Using Log, front-end to the logging chain, emulates android.util.log method signatures.
|
||||
Log.setLogNode(logWrapper);
|
||||
|
||||
// Filter strips out everything except the message text.
|
||||
MessageOnlyLogFilter msgFilter = new MessageOnlyLogFilter();
|
||||
logWrapper.setNext(msgFilter);
|
||||
|
||||
// On screen logging via a fragment with a TextView.
|
||||
LogFragment logFragment = (LogFragment) getSupportFragmentManager()
|
||||
.findFragmentById(R.id.log_fragment);
|
||||
msgFilter.setNext(logFragment.getLogView());
|
||||
|
||||
Log.i(TAG, "Ready");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user