upload android base code part7

This commit is contained in:
August 2018-08-08 18:09:17 +08:00
parent 4e516ec6ed
commit 841ae54672
25229 changed files with 1709508 additions and 0 deletions

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.insertingcells"
android:versionCode="1"
android:versionName="1.0">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-sdk android:minSdkVersion="14"
android:targetSdkVersion="17"/>
<application android:label="@string/app_name" android:icon="@drawable/ic_launcher">
<activity android:name=".InsertingCells"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View file

@ -0,0 +1,53 @@
<!-- Copyright (C) 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.
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/relative_layout"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity"
android:background="#111">
<LinearLayout
android:id="@+id/linear_layout"
android:layout_height="@dimen/cell_height"
android:layout_width="match_parent"
android:orientation="horizontal">
<com.example.android.insertingcells.RoundView
android:id="@+id/round_view"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"/>
<Button
android:id="@+id/add_row_button"
android:layout_width="0dp"
android:layout_height="match_parent"
android:text="@string/add_row"
android:onClick="addRow"
android:layout_weight="2"/>
</LinearLayout>
<com.example.android.insertingcells.InsertionListView
android:id="@+id/listview"
android:layout_below="@id/linear_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>

View file

@ -0,0 +1,40 @@
<!-- Copyright (C) 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.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/item_linear_layout"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="horizontal"
android:background="@drawable/border">
<ImageView
android:id="@+id/image_view"
android:layout_height="match_parent"
android:layout_width="0dp"
android:gravity="center_vertical"
android:layout_weight="1"
android:scaleType="center"/>
<TextView
android:id="@+id/text_view"
android:layout_height="fill_parent"
android:layout_width="0dp"
android:gravity="center"
android:layout_weight="2"
android:textStyle="bold"
android:textSize="22sp"
android:textColor="#ffffff"/>
</LinearLayout>

View file

@ -0,0 +1,21 @@
<!-- Copyright (C) 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.
-->
<resources>
<dimen name="circle_radius">50dp</dimen>
<dimen name="cell_height">150dp</dimen>
</resources>

View file

@ -0,0 +1,21 @@
<!-- Copyright (C) 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.
-->
<resources>
<string name="app_name">InsertingCells</string>
<string name="add_row">Add Row</string>
</resources>

View file

@ -0,0 +1,138 @@
/*
* Copyright (C) 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.insertingcells;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import java.util.HashMap;
import java.util.List;
/**
* This custom array adapter is used to populate the ListView in this application.
* This adapter also maintains a map of unique stable ids for each object in the data set.
* Since this adapter has to support the addition of a new cell to the 1ist index, it also
* provides a mechanism to add a stable ID for new data that was recently inserted.
*/
public class CustomArrayAdapter extends ArrayAdapter<ListItemObject> {
HashMap<ListItemObject, Integer> mIdMap = new HashMap<ListItemObject, Integer>();
List<ListItemObject> mData;
Context mContext;
int mLayoutViewResourceId;
int mCounter;
public CustomArrayAdapter(Context context, int layoutViewResourceId,
List <ListItemObject> data) {
super(context, layoutViewResourceId, data);
mData = data;
mContext = context;
mLayoutViewResourceId = layoutViewResourceId;
updateStableIds();
}
public long getItemId(int position) {
ListItemObject item = getItem(position);
if (mIdMap.containsKey(item)) {
return mIdMap.get(item);
}
return -1;
}
public void updateStableIds() {
mIdMap.clear();
mCounter = 0;
for (int i = 0; i < mData.size(); ++i) {
mIdMap.put(mData.get(i), mCounter++);
}
}
public void addStableIdForDataAtPosition(int position) {
mIdMap.put(mData.get(position), ++mCounter);
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ListItemObject obj = mData.get(position);
if(convertView == null) {
LayoutInflater inflater = ((Activity)mContext).getLayoutInflater();
convertView = inflater.inflate(mLayoutViewResourceId, parent, false);
}
convertView.setLayoutParams(new ListView.LayoutParams(ListView.LayoutParams
.MATCH_PARENT, obj.getHeight()));
ImageView imgView = (ImageView)convertView.findViewById(R.id.image_view);
TextView textView = (TextView)convertView.findViewById(R.id.text_view);
Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(),
obj.getImgResource(), null);
textView.setText(obj.getTitle());
imgView.setImageBitmap(CustomArrayAdapter.getCroppedBitmap(bitmap));
return convertView;
}
/**
* Returns a circular cropped version of the bitmap passed in.
*/
public static Bitmap getCroppedBitmap(Bitmap bitmap) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(),
Config.ARGB_8888);
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
Canvas canvas = new Canvas(output);
final Paint paint = new Paint();
paint.setAntiAlias(true);
int halfWidth = bitmap.getWidth() / 2;
int halfHeight = bitmap.getHeight() / 2;
canvas.drawCircle(halfWidth, halfHeight, Math.max(halfWidth, halfHeight), paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
}

View file

@ -0,0 +1,113 @@
/*
* Copyright (C) 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.insertingcells;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.RelativeLayout;
import java.util.ArrayList;
import java.util.List;
/**
* This application creates a ListView to which new elements can be added from the
* top. When a new element is added, it is animated from above the bounds
* of the list to the top. When the list is scrolled all the way to the top and a new
* element is added, the row animation is accompanied by an image animation that pops
* out of the round view and pops into the correct position in the top cell.
*/
public class InsertingCells extends Activity implements OnRowAdditionAnimationListener {
private ListItemObject mValues[];
private InsertionListView mListView;
private Button mButton;
private Integer mItemNum = 0;
private RoundView mRoundView;
private int mCellHeight;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mValues = new ListItemObject[] {
new ListItemObject("Chameleon", R.drawable.chameleon, 0),
new ListItemObject("Rock", R.drawable.rock, 0),
new ListItemObject("Flower", R.drawable.flower, 0),
};
mCellHeight = (int)(getResources().getDimension(R.dimen.cell_height));
List<ListItemObject> mData = new ArrayList<ListItemObject>();
CustomArrayAdapter mAdapter = new CustomArrayAdapter(this, R.layout.list_view_item, mData);
RelativeLayout mLayout = (RelativeLayout)findViewById(R.id.relative_layout);
mRoundView = (RoundView)findViewById(R.id.round_view);
mButton = (Button)findViewById(R.id.add_row_button);
mListView = (InsertionListView)findViewById(R.id.listview);
mListView.setAdapter(mAdapter);
mListView.setData(mData);
mListView.setLayout(mLayout);
mListView.setRowAdditionAnimationListener(this);
}
public void addRow(View view) {
mButton.setEnabled(false);
mItemNum++;
ListItemObject obj = mValues[mItemNum % mValues.length];
final ListItemObject newObj = new ListItemObject(obj.getTitle(), obj.getImgResource(),
mCellHeight);
boolean shouldAnimateInNewImage = mListView.shouldAnimateInNewImage();
if (!shouldAnimateInNewImage) {
mListView.addRow(newObj);
return;
}
mListView.setEnabled(false);
ObjectAnimator animator = mRoundView.getScalingAnimator();
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationRepeat(Animator animation) {
mListView.addRow(newObj);
}
});
animator.start();
}
@Override
public void onRowAdditionAnimationStart() {
mButton.setEnabled(false);
}
@Override
public void onRowAdditionAnimationEnd() {
mButton.setEnabled(true);
}
}

View file

@ -0,0 +1,376 @@
/*
* Copyright (C) 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.insertingcells;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.animation.OvershootInterpolator;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* This ListView displays a set of ListItemObjects. By calling addRow with a new
* ListItemObject, it is added to the top of the ListView and the new row is animated
* in. If the ListView content is at the top (the scroll offset is 0), the animation of
* the new row is accompanied by an extra image animation that pops into place in its
* corresponding item in the ListView.
*/
public class InsertionListView extends ListView {
private static final int NEW_ROW_DURATION = 500;
private static final int OVERSHOOT_INTERPOLATOR_TENSION = 5;
private OvershootInterpolator sOvershootInterpolator;
private RelativeLayout mLayout;
private Context mContext;
private OnRowAdditionAnimationListener mRowAdditionAnimationListener;
private List<ListItemObject> mData;
private List<BitmapDrawable> mCellBitmapDrawables;
public InsertionListView(Context context) {
super(context);
init(context);
}
public InsertionListView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public InsertionListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
public void init(Context context) {
setDivider(null);
mContext = context;
mCellBitmapDrawables = new ArrayList<BitmapDrawable>();
sOvershootInterpolator = new OvershootInterpolator(OVERSHOOT_INTERPOLATOR_TENSION);
}
/**
* Modifies the underlying data set and adapter through the addition of the new object
* to the first item of the ListView. The new cell is then animated into place from
* above the bounds of the ListView.
*/
public void addRow(ListItemObject newObj) {
final CustomArrayAdapter adapter = (CustomArrayAdapter)getAdapter();
/**
* Stores the starting bounds and the corresponding bitmap drawables of every
* cell present in the ListView before the data set change takes place.
*/
final HashMap<Long, Rect> listViewItemBounds = new HashMap<Long, Rect>();
final HashMap<Long, BitmapDrawable> listViewItemDrawables = new HashMap<Long,
BitmapDrawable>();
int firstVisiblePosition = getFirstVisiblePosition();
for (int i = 0; i < getChildCount(); ++i) {
View child = getChildAt(i);
int position = firstVisiblePosition + i;
long itemID = adapter.getItemId(position);
Rect startRect = new Rect(child.getLeft(), child.getTop(), child.getRight(),
child.getBottom());
listViewItemBounds.put(itemID, startRect);
listViewItemDrawables.put(itemID, getBitmapDrawableFromView(child));
}
/** Adds the new object to the data set, thereby modifying the adapter,
* as well as adding a stable Id for that specified object.*/
mData.add(0, newObj);
adapter.addStableIdForDataAtPosition(0);
adapter.notifyDataSetChanged();
final ViewTreeObserver observer = getViewTreeObserver();
observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
observer.removeOnPreDrawListener(this);
ArrayList<Animator> animations = new ArrayList<Animator>();
final View newCell = getChildAt(0);
final ImageView imgView = (ImageView)newCell.findViewById(R.id.image_view);
final ImageView copyImgView = new ImageView(mContext);
int firstVisiblePosition = getFirstVisiblePosition();
final boolean shouldAnimateInNewRow = shouldAnimateInNewRow();
final boolean shouldAnimateInImage = shouldAnimateInNewImage();
if (shouldAnimateInNewRow) {
/** Fades in the text of the first cell. */
TextView textView = (TextView)newCell.findViewById(R.id.text_view);
ObjectAnimator textAlphaAnimator = ObjectAnimator.ofFloat(textView,
View.ALPHA, 0.0f, 1.0f);
animations.add(textAlphaAnimator);
/** Animates in the extra hover view corresponding to the image
* in the top row of the ListView. */
if (shouldAnimateInImage) {
int width = imgView.getWidth();
int height = imgView.getHeight();
Point childLoc = getLocationOnScreen(newCell);
Point layoutLoc = getLocationOnScreen(mLayout);
ListItemObject obj = mData.get(0);
Bitmap bitmap = CustomArrayAdapter.getCroppedBitmap(BitmapFactory
.decodeResource(mContext.getResources(), obj.getImgResource(),
null));
copyImgView.setImageBitmap(bitmap);
imgView.setVisibility(View.INVISIBLE);
copyImgView.setScaleType(ImageView.ScaleType.CENTER);
ObjectAnimator imgViewTranslation = ObjectAnimator.ofFloat(copyImgView,
View.Y, childLoc.y - layoutLoc.y);
PropertyValuesHolder imgViewScaleY = PropertyValuesHolder.ofFloat
(View.SCALE_Y, 0, 1.0f);
PropertyValuesHolder imgViewScaleX = PropertyValuesHolder.ofFloat
(View.SCALE_X, 0, 1.0f);
ObjectAnimator imgViewScaleAnimator = ObjectAnimator
.ofPropertyValuesHolder(copyImgView, imgViewScaleX, imgViewScaleY);
imgViewScaleAnimator.setInterpolator(sOvershootInterpolator);
animations.add(imgViewTranslation);
animations.add(imgViewScaleAnimator);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams
(width, height);
mLayout.addView(copyImgView, params);
}
}
/** Loops through all the current visible cells in the ListView and animates
* all of them into their post layout positions from their original positions.*/
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
int position = firstVisiblePosition + i;
long itemId = adapter.getItemId(position);
Rect startRect = listViewItemBounds.get(itemId);
int top = child.getTop();
if (startRect != null) {
/** If the cell was visible before the data set change and
* after the data set change, then animate the cell between
* the two positions.*/
int startTop = startRect.top;
int delta = startTop - top;
ObjectAnimator animation = ObjectAnimator.ofFloat(child,
View.TRANSLATION_Y, delta, 0);
animations.add(animation);
} else {
/** If the cell was not visible (or present) before the data set
* change but is visible after the data set change, then use its
* height to determine the delta by which it should be animated.*/
int childHeight = child.getHeight() + getDividerHeight();
int startTop = top + (i > 0 ? childHeight : -childHeight);
int delta = startTop - top;
ObjectAnimator animation = ObjectAnimator.ofFloat(child,
View.TRANSLATION_Y, delta, 0);
animations.add(animation);
}
listViewItemBounds.remove(itemId);
listViewItemDrawables.remove(itemId);
}
/**
* Loops through all the cells that were visible before the data set
* changed but not after, and keeps track of their corresponding
* drawables. The bounds of each drawable are then animated from the
* original state to the new one (off the screen). By storing all
* the drawables that meet this criteria, they can be redrawn on top
* of the ListView via dispatchDraw as they are animating.
*/
for (Long itemId: listViewItemBounds.keySet()) {
BitmapDrawable bitmapDrawable = listViewItemDrawables.get(itemId);
Rect startBounds = listViewItemBounds.get(itemId);
bitmapDrawable.setBounds(startBounds);
int childHeight = startBounds.bottom - startBounds.top + getDividerHeight();
Rect endBounds = new Rect(startBounds);
endBounds.offset(0, childHeight);
ObjectAnimator animation = ObjectAnimator.ofObject(bitmapDrawable,
"bounds", sBoundsEvaluator, startBounds, endBounds);
animation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
private Rect mLastBound = null;
private Rect mCurrentBound = new Rect();
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
Rect bounds = (Rect)valueAnimator.getAnimatedValue();
mCurrentBound.set(bounds);
if (mLastBound != null) {
mCurrentBound.union(mLastBound);
}
mLastBound = bounds;
invalidate(mCurrentBound);
}
});
listViewItemBounds.remove(itemId);
listViewItemDrawables.remove(itemId);
mCellBitmapDrawables.add(bitmapDrawable);
animations.add(animation);
}
/** Animates all the cells from their old position to their new position
* at the same time.*/
setEnabled(false);
mRowAdditionAnimationListener.onRowAdditionAnimationStart();
AnimatorSet set = new AnimatorSet();
set.setDuration(NEW_ROW_DURATION);
set.playTogether(animations);
set.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mCellBitmapDrawables.clear();
imgView.setVisibility(View.VISIBLE);
mLayout.removeView(copyImgView);
mRowAdditionAnimationListener.onRowAdditionAnimationEnd();
setEnabled(true);
invalidate();
}
});
set.start();
listViewItemBounds.clear();
listViewItemDrawables.clear();
return true;
}
});
}
/**
* By overriding dispatchDraw, the BitmapDrawables of all the cells that were on the
* screen before (but not after) the layout are drawn and animated off the screen.
*/
@Override
protected void dispatchDraw (Canvas canvas) {
super.dispatchDraw(canvas);
if (mCellBitmapDrawables.size() > 0) {
for (BitmapDrawable bitmapDrawable: mCellBitmapDrawables) {
bitmapDrawable.draw(canvas);
}
}
}
public boolean shouldAnimateInNewRow() {
int firstVisiblePosition = getFirstVisiblePosition();
return (firstVisiblePosition == 0);
}
public boolean shouldAnimateInNewImage() {
if (getChildCount() == 0) {
return true;
}
boolean shouldAnimateInNewRow = shouldAnimateInNewRow();
View topCell = getChildAt(0);
return (shouldAnimateInNewRow && topCell.getTop() == 0);
}
/** Returns a bitmap drawable showing a screenshot of the view passed in. */
private BitmapDrawable getBitmapDrawableFromView(View v) {
Bitmap bitmap = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas (bitmap);
v.draw(canvas);
return new BitmapDrawable(getResources(), bitmap);
}
/**
* Returns the absolute x,y coordinates of the view relative to the top left
* corner of the phone screen.
*/
public Point getLocationOnScreen(View v) {
DisplayMetrics dm = new DisplayMetrics();
((Activity)getContext()).getWindowManager().getDefaultDisplay().getMetrics(dm);
int[] location = new int[2];
v.getLocationOnScreen(location);
return new Point(location[0], location[1]);
}
/** Setter for the underlying data set controlling the adapter. */
public void setData(List<ListItemObject> data) {
mData = data;
}
/**
* Setter for the parent RelativeLayout of this ListView. A reference to this
* ViewGroup is required in order to add the custom animated overlaying bitmap
* when adding a new row.
*/
public void setLayout(RelativeLayout layout) {
mLayout = layout;
}
public void setRowAdditionAnimationListener(OnRowAdditionAnimationListener
rowAdditionAnimationListener) {
mRowAdditionAnimationListener = rowAdditionAnimationListener;
}
/**
* This TypeEvaluator is used to animate the position of a BitmapDrawable
* by updating its bounds.
*/
static final TypeEvaluator<Rect> sBoundsEvaluator = new TypeEvaluator<Rect>() {
public Rect evaluate(float fraction, Rect startValue, Rect endValue) {
return new Rect(interpolate(startValue.left, endValue.left, fraction),
interpolate(startValue.top, endValue.top, fraction),
interpolate(startValue.right, endValue.right, fraction),
interpolate(startValue.bottom, endValue.bottom, fraction));
}
public int interpolate(int start, int end, float fraction) {
return (int)(start + fraction * (end - start));
}
};
}

View file

@ -0,0 +1,48 @@
/*
* Copyright (C) 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.insertingcells;
/**
* The data model for every cell in the ListView for this application. This model stores
* a title, an image resource and a default cell height for every item in the ListView.
*/
public class ListItemObject {
private String mTitle;
private int mImgResource;
private int mHeight;
public ListItemObject(String title, int imgResource, int height) {
super();
mTitle = title;
mImgResource = imgResource;
mHeight = height;
}
public String getTitle() {
return mTitle;
}
public int getImgResource() {
return mImgResource;
}
public int getHeight() {
return mHeight;
}
}

View file

@ -0,0 +1,28 @@
/*
* Copyright (C) 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.insertingcells;
/**
* This listener is used to determine when the animation of a new row addition
* begins and ends. The primary use of this interface is to create a callback
* under which certain elements, such as the listview itself, can be disabled
* to prevent unpredictable behaviour during the actual cell animation.
*/
public interface OnRowAdditionAnimationListener {
public void onRowAdditionAnimationStart();
public void onRowAdditionAnimationEnd();
}

View file

@ -0,0 +1,85 @@
/*
* Copyright (C) 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.insertingcells;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
/**
* This round view draws a circle from which the image pops out of and into
* the corresponding cell in the list.
*/
public class RoundView extends View {
private final int STROKE_WIDTH = 6;
private final int RADIUS = 20;
private final int ANIMATION_DURATION = 300;
private final float SCALE_FACTOR = 0.3f;
private Paint mPaint;
public RoundView(Context context) {
super(context);
init();
}
public RoundView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public RoundView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(Color.WHITE);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(STROKE_WIDTH);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawCircle(canvas.getWidth() / 2, canvas.getHeight() / 2,
RADIUS, mPaint);
}
public ObjectAnimator getScalingAnimator() {
PropertyValuesHolder imgViewScaleY = PropertyValuesHolder.ofFloat(View
.SCALE_Y, SCALE_FACTOR);
PropertyValuesHolder imgViewScaleX = PropertyValuesHolder.ofFloat(View
.SCALE_X, SCALE_FACTOR);
ObjectAnimator imgViewScaleAnimator = ObjectAnimator
.ofPropertyValuesHolder(this, imgViewScaleX, imgViewScaleY);
imgViewScaleAnimator.setRepeatCount(1);
imgViewScaleAnimator.setRepeatMode(ValueAnimator.REVERSE);
imgViewScaleAnimator.setDuration(ANIMATION_DURATION);
return imgViewScaleAnimator;
}
}