From 26550ad42735a7336a2df1b7c57d4a8e977a59d9 Mon Sep 17 00:00:00 2001 From: Daniel Olshansky Date: Tue, 25 Jun 2013 15:09:04 -0700 Subject: [PATCH] First commit for ListViewExpandingCells. Change-Id: I8d64562f8c7c0e207aef0b36df10ee3744dd446a (cherry picked from commit 8cfd63c979293145b068ffdf14a24b3ea87c7267) --- .../AndroidManifest.xml | 17 + .../res/drawable-hdpi/border.9.png | Bin 0 -> 96 bytes .../res/drawable-hdpi/chameleon.jpg | Bin 0 -> 7486 bytes .../res/drawable-hdpi/flower.jpg | Bin 0 -> 8856 bytes .../res/drawable-hdpi/ic_launcher.png | Bin 0 -> 9397 bytes .../res/drawable-hdpi/rock.jpg | Bin 0 -> 21206 bytes .../res/drawable-ldpi/ic_launcher.png | Bin 0 -> 2729 bytes .../res/drawable-mdpi/ic_launcher.png | Bin 0 -> 5237 bytes .../res/drawable-xhdpi/ic_launcher.png | Bin 0 -> 14383 bytes .../res/layout/activity_main.xml | 21 + .../res/layout/list_view_item.xml | 68 +++ .../res/values/strings.xml | 23 + .../expandingcells/CustomArrayAdapter.java | 133 +++++ .../expandingcells/ExpandableListItem.java | 87 +++ .../expandingcells/ExpandingCells.java | 71 +++ .../expandingcells/ExpandingLayout.java | 79 +++ .../expandingcells/ExpandingListView.java | 540 ++++++++++++++++++ .../expandingcells/OnSizeChangedListener.java | 25 + 18 files changed, 1064 insertions(+) create mode 100644 samples/devbytes/animation/ListViewExpandingCells/AndroidManifest.xml create mode 100644 samples/devbytes/animation/ListViewExpandingCells/res/drawable-hdpi/border.9.png create mode 100644 samples/devbytes/animation/ListViewExpandingCells/res/drawable-hdpi/chameleon.jpg create mode 100644 samples/devbytes/animation/ListViewExpandingCells/res/drawable-hdpi/flower.jpg create mode 100644 samples/devbytes/animation/ListViewExpandingCells/res/drawable-hdpi/ic_launcher.png create mode 100644 samples/devbytes/animation/ListViewExpandingCells/res/drawable-hdpi/rock.jpg create mode 100644 samples/devbytes/animation/ListViewExpandingCells/res/drawable-ldpi/ic_launcher.png create mode 100644 samples/devbytes/animation/ListViewExpandingCells/res/drawable-mdpi/ic_launcher.png create mode 100644 samples/devbytes/animation/ListViewExpandingCells/res/drawable-xhdpi/ic_launcher.png create mode 100644 samples/devbytes/animation/ListViewExpandingCells/res/layout/activity_main.xml create mode 100644 samples/devbytes/animation/ListViewExpandingCells/res/layout/list_view_item.xml create mode 100644 samples/devbytes/animation/ListViewExpandingCells/res/values/strings.xml create mode 100644 samples/devbytes/animation/ListViewExpandingCells/src/com/example/android/expandingcells/CustomArrayAdapter.java create mode 100644 samples/devbytes/animation/ListViewExpandingCells/src/com/example/android/expandingcells/ExpandableListItem.java create mode 100644 samples/devbytes/animation/ListViewExpandingCells/src/com/example/android/expandingcells/ExpandingCells.java create mode 100644 samples/devbytes/animation/ListViewExpandingCells/src/com/example/android/expandingcells/ExpandingLayout.java create mode 100644 samples/devbytes/animation/ListViewExpandingCells/src/com/example/android/expandingcells/ExpandingListView.java create mode 100644 samples/devbytes/animation/ListViewExpandingCells/src/com/example/android/expandingcells/OnSizeChangedListener.java diff --git a/samples/devbytes/animation/ListViewExpandingCells/AndroidManifest.xml b/samples/devbytes/animation/ListViewExpandingCells/AndroidManifest.xml new file mode 100644 index 000000000..1633d01f4 --- /dev/null +++ b/samples/devbytes/animation/ListViewExpandingCells/AndroidManifest.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + diff --git a/samples/devbytes/animation/ListViewExpandingCells/res/drawable-hdpi/border.9.png b/samples/devbytes/animation/ListViewExpandingCells/res/drawable-hdpi/border.9.png new file mode 100644 index 0000000000000000000000000000000000000000..f76e008e936980970a0ca473b5219f9275a3107c GIT binary patch literal 96 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1p!3HD`EN_1Yq|`lK978H@B_}vE{O385aJ*0U uf1-q*hN|jU`L>6*HgG0|cHZ?VVPKdXt}yS>gC2dL76wmOKbLh*2~7aJKpn9F literal 0 HcmV?d00001 diff --git a/samples/devbytes/animation/ListViewExpandingCells/res/drawable-hdpi/chameleon.jpg b/samples/devbytes/animation/ListViewExpandingCells/res/drawable-hdpi/chameleon.jpg new file mode 100644 index 0000000000000000000000000000000000000000..686cc8814cb2e7771217ed698080279ced1625d7 GIT binary patch literal 7486 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 literal 0 HcmV?d00001 diff --git a/samples/devbytes/animation/ListViewExpandingCells/res/drawable-hdpi/flower.jpg b/samples/devbytes/animation/ListViewExpandingCells/res/drawable-hdpi/flower.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8842483b274778febf6a5bb04751b98d9a1098d8 GIT binary patch literal 8856 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 AVgLXD literal 0 HcmV?d00001 diff --git a/samples/devbytes/animation/ListViewExpandingCells/res/drawable-hdpi/ic_launcher.png b/samples/devbytes/animation/ListViewExpandingCells/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..96a442e5b8e9394ccf50bab9988cb2316026245d GIT binary patch literal 9397 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 TiuDyV`F+T8t5aHQ>VN;)BRhSx literal 0 HcmV?d00001 diff --git a/samples/devbytes/animation/ListViewExpandingCells/res/drawable-ldpi/ic_launcher.png b/samples/devbytes/animation/ListViewExpandingCells/res/drawable-ldpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..99238729d8753585237a65b91c7cde426c90baef GIT binary patch literal 2729 zcmV;a3Rd-rP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L02dMf02dMgXP?qi00007bV*G`2ipt~ z7YY(F`_Sb8017EdL_t(o!?l=uuwPYm$3JVI^ZWho?|E--5|R`W6G$K=z*GYY6wr=V zEHLAs& zdz|M!d-acV?}e00xbt)P@m$z^s#fV*k#SgXB4;4pFT(w@xz)o_l~EwJ+$tL zNA}&l{N}CqzO8^B)M@;g^aHT<;0E84yNhu{N${eJ-?VeV-AUA6q$<9trt}a{U45TFsn9Sc6zfp($j8t2s@dE zQIjAUBn)CY?J)11fS?@`1`%Nx6NL#$Z0Usk7(Wr4STgIdiMw7!!ptNtBYrmL$nY(+rzsSZg&+Q(Pts z$DVsczi`HH^ri&>wJ9FAf9p&De1OdZH!;t<6V-n!4>5RGht>sq2l{?Fa6~?LaQm$9 z9qH`6yjb)4PhAIa?cbkttcHHF=ZgDOlWSCc`VaTB=hp)doVH}{g9J0z z{OG}rx?{_LG>2kT!Sf8oqKD@j#DD_oG}lq0#F53O8AgO^qo8w6oGP^*|D}1SXUk7K zb?V*KdY9iC3G_f;Tb_CB@TqH89N00=&{%tU%c0Z4WB~ApI*tQ-I@60@=bck#y}*T6 z_R1w!Pet&si6M<0X$&@1Z04|OhSLnh!5CX8&N-6E$;g1?;NIcJ!9M@ET6asjDj{j& zq&1Y$9Lh>#7>)s?>Lr;~P$jdD%&Hf*{8+t^cGKb)1Y-;$qr{4!>WIP!krE;qzA0ie zH@2QMam0}lG!0Rtu2d9Jhk!tC3eGyD1bu2t1_*& znD@VXDUHfZeztiTyAJ-0ENzq8EH4L{qM4F8hdRitic@fz!#TyN5{GdxF+&jQ7@$l6 zDL9*@Sw_A%6O4hL>RjG2?L1CC{!f_IyJ&pj%>v_aJj(1 zDV}G@zl}MeEcR)=MBzMj!s=}<^ zGdSzCOStu`m-76U#|fg&xSoPB<%f3P={hr%`p}{nf+USozR$hK7$G3*$9{2!b{no?XWStM8y#?82#n6GW?7)Zsa` zwL!I2XXA1vS#2G_6uFg)uUPcjE9|${UC9d@_w0xRuPYew-0*;GI=nx){rvMUu(54@ z+`1-W3}TdRyVvvF=0|BZ+svA_fYc`R9sDKlJoSV8^oiAcd+nE5_tZVqd%^b&f>BQz zGBTL-|M&8(H=O;xQ=e^A=e^iz^4+6@yKlSf%8Tv#hqkcmS4VRN-hS^#_`+wt2f#&F zoaoiN8`U^;=?_+H4ewj^5AQhK+SC`?KJ^PeVnke)?{!I}B<(sU&3He<>2?MWWu%2Z z{8ENr@N(U$qFI3=v-$PTS07#Z@0&k3QOG}i+j)HBi%%Z=`tcW^UCejx+4hFXpTF~> z6_NH`)m1V01y2Phns1H@BEv%=rBZ<`6)ly05y^ASTBkN~;?g=vr9P;=m7CX$|G)Zgm+aiXZ~uaNy+(I$oqD4|rBaJZ zrIPx7!4u>8HcdFJC#TdexmzBje$|6hQ{z`W;j zcxEL`omomE>(d+x8Qd8VhX=5+`P#GV58evMdoP*&lTI}9fl8%JsjEQ2FXPkIUzaTk zaNk#c^;wYqAW|>-DX%0C?1}#Zoic`Di%g1kcS7qn!=Ut&(rcy6c zEP5*Vl6GWL2O9olCKpP^6ib5fJT(SUCo~-tix$s^a?N*TuSl&?#P^M4X@Pb!L1}-x z&WA*#CC1=+BE_;txmKWDDTfD-_Gz_Ib&Z~KTI()QX%w`p;#2A}c%F3r-vD)*@$xL` zN{seU@}^QO)(>T_xfWpdaeovRE7^CZPMr}#|!d*|R6{H=+M{MV$Mp3LNPKT_t5 z(-+S5yz=?J*A+!U{KSTh8xFttSbqQdFU>bSjT8Q$)Ky#JnbOd}k;7ZR_W37=|NQzh jFn-Lp|K;W1YU6(Zg`N}+zmb=x00000NkvXXu0mjf_|!_9 literal 0 HcmV?d00001 diff --git a/samples/devbytes/animation/ListViewExpandingCells/res/drawable-mdpi/ic_launcher.png b/samples/devbytes/animation/ListViewExpandingCells/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..359047dfa4ed206e41e2354f9c6b307e713efe32 GIT binary patch literal 5237 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 literal 0 HcmV?d00001 diff --git a/samples/devbytes/animation/ListViewExpandingCells/res/drawable-xhdpi/ic_launcher.png b/samples/devbytes/animation/ListViewExpandingCells/res/drawable-xhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..71c6d760f05183ef8a47c614d8d13380c8528499 GIT binary patch literal 14383 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 literal 0 HcmV?d00001 diff --git a/samples/devbytes/animation/ListViewExpandingCells/res/layout/activity_main.xml b/samples/devbytes/animation/ListViewExpandingCells/res/layout/activity_main.xml new file mode 100644 index 000000000..d904a585d --- /dev/null +++ b/samples/devbytes/animation/ListViewExpandingCells/res/layout/activity_main.xml @@ -0,0 +1,21 @@ + + diff --git a/samples/devbytes/animation/ListViewExpandingCells/res/layout/list_view_item.xml b/samples/devbytes/animation/ListViewExpandingCells/res/layout/list_view_item.xml new file mode 100644 index 000000000..c2c22091d --- /dev/null +++ b/samples/devbytes/animation/ListViewExpandingCells/res/layout/list_view_item.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/devbytes/animation/ListViewExpandingCells/res/values/strings.xml b/samples/devbytes/animation/ListViewExpandingCells/res/values/strings.xml new file mode 100644 index 000000000..1fcee40c8 --- /dev/null +++ b/samples/devbytes/animation/ListViewExpandingCells/res/values/strings.xml @@ -0,0 +1,23 @@ + + + + + ExpandingCells + Lorem ipsum dolor sit amet, consectetur adipiscing elit + "Pellentesque dictum sit amet sapien in faucibus. Curabitur fermentum, nulla quis placerat imperdiet, est nisi placerat arcu, non ornare erat justo at enim. Nam vitae porttitor sem. Quisque non quam nisi. Proin quis urna id elit ultrices cursus non tempus dolor" + "Mauris dapibus convallis massa, vitae ultrices est ultricies ut. Nam porttitor et metus ac bibendum. Nam at justo vitae felis lacinia ultrices laoreet ut arcu. Nam ac purus et turpis convallis mollis. Integer lorem eros, hendrerit imperdiet interdum vitae, sagittis eget ipsum. Donec dignissim tortor at felis fringilla, sed dignissim diam vulputate. Nam sit amet facilisis massa. Suspendisse posuere quam quis augue dapibus venenatis." + + diff --git a/samples/devbytes/animation/ListViewExpandingCells/src/com/example/android/expandingcells/CustomArrayAdapter.java b/samples/devbytes/animation/ListViewExpandingCells/src/com/example/android/expandingcells/CustomArrayAdapter.java new file mode 100644 index 000000000..68919a25e --- /dev/null +++ b/samples/devbytes/animation/ListViewExpandingCells/src/com/example/android/expandingcells/CustomArrayAdapter.java @@ -0,0 +1,133 @@ +/* + * 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.expandingcells; + +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.AbsListView; +import android.widget.ArrayAdapter; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ListView; +import android.widget.TextView; + +import java.util.List; + +/** + * This is a custom array adapter used to populate the listview whose items will + * expand to display extra content in addition to the default display. + */ +public class CustomArrayAdapter extends ArrayAdapter { + + private List mData; + private int mLayoutViewResourceId; + + public CustomArrayAdapter(Context context, int layoutViewResourceId, + List data) { + super(context, layoutViewResourceId, data); + mData = data; + mLayoutViewResourceId = layoutViewResourceId; + } + + /** + * Populates the item in the listview cell with the appropriate data. This method + * sets the thumbnail image, the title and the extra text. This method also updates + * the layout parameters of the item's view so that the image and title are centered + * in the bounds of the collapsed view, and such that the extra text is not displayed + * in the collapsed state of the cell. + */ + @Override + public View getView(int position, View convertView, ViewGroup parent) { + + final ExpandableListItem object = mData.get(position); + + if(convertView == null) { + LayoutInflater inflater = ((Activity) getContext()).getLayoutInflater(); + convertView = inflater.inflate(mLayoutViewResourceId, parent, false); + } + + LinearLayout linearLayout = (LinearLayout)(convertView.findViewById( + R.id.item_linear_layout)); + LinearLayout.LayoutParams linearLayoutParams = new LinearLayout.LayoutParams + (AbsListView.LayoutParams.MATCH_PARENT, object.getCollapsedHeight()); + linearLayout.setLayoutParams(linearLayoutParams); + + ImageView imgView = (ImageView)convertView.findViewById(R.id.image_view); + TextView titleView = (TextView)convertView.findViewById(R.id.title_view); + TextView textView = (TextView)convertView.findViewById(R.id.text_view); + + titleView.setText(object.getTitle()); + imgView.setImageBitmap(getCroppedBitmap(BitmapFactory.decodeResource(getContext() + .getResources(), object.getImgResource(), null))); + textView.setText(object.getText()); + + convertView.setLayoutParams(new ListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT, + AbsListView.LayoutParams.WRAP_CONTENT)); + + ExpandingLayout expandingLayout = (ExpandingLayout)convertView.findViewById(R.id + .expanding_layout); + expandingLayout.setExpandedHeight(object.getExpandedHeight()); + expandingLayout.setSizeChangedListener(object); + + if (!object.isExpanded()) { + expandingLayout.setVisibility(View.GONE); + } else { + expandingLayout.setVisibility(View.VISIBLE); + } + + return convertView; + } + + /** + * Crops a circle out of the thumbnail photo. + */ + public 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; + } + + +} \ No newline at end of file diff --git a/samples/devbytes/animation/ListViewExpandingCells/src/com/example/android/expandingcells/ExpandableListItem.java b/samples/devbytes/animation/ListViewExpandingCells/src/com/example/android/expandingcells/ExpandableListItem.java new file mode 100644 index 000000000..1eb4fc088 --- /dev/null +++ b/samples/devbytes/animation/ListViewExpandingCells/src/com/example/android/expandingcells/ExpandableListItem.java @@ -0,0 +1,87 @@ +/* + * 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.expandingcells; + +/** + * This custom object is used to populate the list adapter. It contains a reference + * to an image, title, and the extra text to be displayed. Furthermore, it keeps track + * of the current state (collapsed/expanded) of the corresponding item in the list, + * as well as store the height of the cell in its collapsed state. + */ +public class ExpandableListItem implements OnSizeChangedListener { + + private String mTitle; + private String mText; + private boolean mIsExpanded; + private int mImgResource; + private int mCollapsedHeight; + private int mExpandedHeight; + + public ExpandableListItem(String title, int imgResource, int collapsedHeight, String text) { + mTitle = title; + mImgResource = imgResource; + mCollapsedHeight = collapsedHeight; + mIsExpanded = false; + mText = text; + mExpandedHeight = -1; + } + + public boolean isExpanded() { + return mIsExpanded; + } + + public void setExpanded(boolean isExpanded) { + mIsExpanded = isExpanded; + } + + public String getTitle() { + return mTitle; + } + + public int getImgResource() { + return mImgResource; + } + + public int getCollapsedHeight() { + return mCollapsedHeight; + } + + public void setCollapsedHeight(int collapsedHeight) { + mCollapsedHeight = collapsedHeight; + } + + public String getText() { + return mText; + } + + public void setText(String text) { + mText = text; + } + + public int getExpandedHeight() { + return mExpandedHeight; + } + + public void setExpandedHeight(int expandedHeight) { + mExpandedHeight = expandedHeight; + } + + @Override + public void onSizeChanged(int newHeight) { + setExpandedHeight(newHeight); + } +} diff --git a/samples/devbytes/animation/ListViewExpandingCells/src/com/example/android/expandingcells/ExpandingCells.java b/samples/devbytes/animation/ListViewExpandingCells/src/com/example/android/expandingcells/ExpandingCells.java new file mode 100644 index 000000000..6d6d4f1f8 --- /dev/null +++ b/samples/devbytes/animation/ListViewExpandingCells/src/com/example/android/expandingcells/ExpandingCells.java @@ -0,0 +1,71 @@ +/* + * 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.expandingcells; + +import android.app.Activity; +import android.os.Bundle; + +import java.util.ArrayList; +import java.util.List; + +/** + * This activity creates a listview whose items can be clicked to expand and show + * additional content. + * + * In this specific demo, each item in a listview displays an image and a corresponding + * title. These two items are centered in the default (collapsed) state of the listview's + * item. When the item is clicked, it expands to display text of some varying length. + * The item persists in this expanded state (even if the user scrolls away and then scrolls + * back to the same location) until it is clicked again, at which point the cell collapses + * back to its default state. + */ +public class ExpandingCells extends Activity { + + private final int CELL_DEFAULT_HEIGHT = 200; + private final int NUM_OF_CELLS = 30; + + private ExpandingListView mListView; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + ExpandableListItem[] values = new ExpandableListItem[] { + new ExpandableListItem("Chameleon", R.drawable.chameleon, CELL_DEFAULT_HEIGHT, + getResources().getString(R.string.short_lorem_ipsum)), + new ExpandableListItem("Rock", R.drawable.rock, CELL_DEFAULT_HEIGHT, + getResources().getString(R.string.medium_lorem_ipsum)), + new ExpandableListItem("Flower", R.drawable.flower, CELL_DEFAULT_HEIGHT, + getResources().getString(R.string.long_lorem_ipsum)), + }; + + List mData = new ArrayList(); + + for (int i = 0; i < NUM_OF_CELLS; i++) { + ExpandableListItem obj = values[i % values.length]; + mData.add(new ExpandableListItem(obj.getTitle(), obj.getImgResource(), + obj.getCollapsedHeight(), obj.getText())); + } + + CustomArrayAdapter adapter = new CustomArrayAdapter(this, R.layout.list_view_item, mData); + + mListView = (ExpandingListView)findViewById(R.id.main_list_view); + mListView.setAdapter(adapter); + mListView.setDivider(null); + } +} \ No newline at end of file diff --git a/samples/devbytes/animation/ListViewExpandingCells/src/com/example/android/expandingcells/ExpandingLayout.java b/samples/devbytes/animation/ListViewExpandingCells/src/com/example/android/expandingcells/ExpandingLayout.java new file mode 100644 index 000000000..5add667cd --- /dev/null +++ b/samples/devbytes/animation/ListViewExpandingCells/src/com/example/android/expandingcells/ExpandingLayout.java @@ -0,0 +1,79 @@ +/* + * 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.expandingcells; + +import android.content.Context; +import android.util.AttributeSet; +import android.widget.RelativeLayout; + +/** + * This layout is used to contain the extra information that will be displayed + * when a certain cell is expanded. The custom relative layout is created in + * order to achieve a fading affect of this layout's contents as it is being + * expanded or collapsed as opposed to just fading the content in(out) after(before) + * the cell expands(collapses). + * + * During expansion, layout takes place so the full contents of this layout can + * be displayed. When the size changes to display the full contents of the layout, + * its height is stored. When the view is collapsing, this layout's height becomes 0 + * since it is no longer in the visible part of the cell.By overriding onMeasure, and + * setting the height back to its max height, it is still visible during the collapse + * animation, and so, a fade out effect can be achieved. + */ +public class ExpandingLayout extends RelativeLayout { + + + private OnSizeChangedListener mSizeChangedListener; + private int mExpandedHeight = -1; + + public ExpandingLayout(Context context) { + super(context); + } + + public ExpandingLayout(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public ExpandingLayout(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) { + if (mExpandedHeight > 0) { + heightMeasureSpec = MeasureSpec.makeMeasureSpec(mExpandedHeight, MeasureSpec.AT_MOST); + } + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } + + protected void onSizeChanged (int w, int h, int oldw, int oldh) { + mExpandedHeight = h; + //Notifies the list data object corresponding to this layout that its size has changed. + mSizeChangedListener.onSizeChanged(h); + } + + public int getExpandedHeight() { + return mExpandedHeight; + } + + public void setExpandedHeight(int expandedHeight) { + mExpandedHeight = expandedHeight; + } + + public void setSizeChangedListener(OnSizeChangedListener listener) { + mSizeChangedListener = listener; + } +} diff --git a/samples/devbytes/animation/ListViewExpandingCells/src/com/example/android/expandingcells/ExpandingListView.java b/samples/devbytes/animation/ListViewExpandingCells/src/com/example/android/expandingcells/ExpandingListView.java new file mode 100644 index 000000000..0ba5d5fe5 --- /dev/null +++ b/samples/devbytes/animation/ListViewExpandingCells/src/com/example/android/expandingcells/ExpandingListView.java @@ -0,0 +1,540 @@ +/* + * 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.expandingcells; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.AnimatorSet; +import android.animation.ObjectAnimator; +import android.animation.PropertyValuesHolder; +import android.content.Context; +import android.graphics.Canvas; +import android.util.AttributeSet; +import android.view.View; +import android.view.ViewTreeObserver; +import android.widget.AbsListView; +import android.widget.AdapterView; +import android.widget.ListView; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +/** + * A custom listview which supports the preview of extra content corresponding to each cell + * by clicking on the cell to hide and show the extra content. + */ +public class ExpandingListView extends ListView { + + private boolean mShouldRemoveObserver = false; + + private List mViewsToDraw = new ArrayList(); + + private int[] mTranslate; + + public ExpandingListView(Context context) { + super(context); + init(); + } + + public ExpandingListView(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + public ExpandingListView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(); + } + + private void init() { + setOnItemClickListener(mItemClickListener); + } + + /** + * Listens for item clicks and expands or collapses the selected view depending on + * its current state. + */ + private AdapterView.OnItemClickListener mItemClickListener = new AdapterView + .OnItemClickListener() { + @Override + public void onItemClick (AdapterView parent, View view, int position, long id) { + ExpandableListItem viewObject = (ExpandableListItem)getItemAtPosition(getPositionForView + (view)); + if (!viewObject.isExpanded()) { + expandView(view); + } else { + collapseView(view); + } + } + }; + + /** + * Calculates the top and bottom bound changes of the selected item. These values are + * also used to move the bounds of the items around the one that is actually being + * expanded or collapsed. + * + * This method can be modified to achieve different user experiences depending + * on how you want the cells to expand or collapse. In this specific demo, the cells + * always try to expand downwards (leaving top bound untouched), and similarly, + * collapse upwards (leaving top bound untouched). If the change in bounds + * results in the complete disappearance of a cell, its lower bound is moved is + * moved to the top of the screen so as not to hide any additional content that + * the user has not interacted with yet. Furthermore, if the collapsed cell is + * partially off screen when it is first clicked, it is translated such that its + * full contents are visible. Lastly, this behaviour varies slightly near the bottom + * of the listview in order to account for the fact that the bottom bounds of the actual + * listview cannot be modified. + */ + private int[] getTopAndBottomTranslations(int top, int bottom, int yDelta, + boolean isExpanding) { + int yTranslateTop = 0; + int yTranslateBottom = yDelta; + + int height = bottom - top; + + if (isExpanding) { + boolean isOverTop = top < 0; + boolean isBelowBottom = (top + height + yDelta) > getHeight(); + if (isOverTop) { + yTranslateTop = top; + yTranslateBottom = yDelta - yTranslateTop; + } else if (isBelowBottom){ + int deltaBelow = top + height + yDelta - getHeight(); + yTranslateTop = top - deltaBelow < 0 ? top : deltaBelow; + yTranslateBottom = yDelta - yTranslateTop; + } + } else { + int offset = computeVerticalScrollOffset(); + int range = computeVerticalScrollRange(); + int extent = computeVerticalScrollExtent(); + int leftoverExtent = range-offset - extent; + + boolean isCollapsingBelowBottom = (yTranslateBottom > leftoverExtent); + boolean isCellCompletelyDisappearing = bottom - yTranslateBottom < 0; + + if (isCollapsingBelowBottom) { + yTranslateTop = yTranslateBottom - leftoverExtent; + yTranslateBottom = yDelta - yTranslateTop; + } else if (isCellCompletelyDisappearing) { + yTranslateBottom = bottom; + yTranslateTop = yDelta - yTranslateBottom; + } + } + + return new int[] {yTranslateTop, yTranslateBottom}; + } + + /** + * This method expands the view that was clicked and animates all the views + * around it to make room for the expanding view. There are several steps required + * to do this which are outlined below. + * + * 1. Store the current top and bottom bounds of each visible item in the listview. + * 2. Update the layout parameters of the selected view. In the context of this + * method, the view should be originally collapsed and set to some custom height. + * The layout parameters are updated so as to wrap the content of the additional + * text that is to be displayed. + * + * After invoking a layout to take place, the listview will order all the items + * such that there is space for each view. This layout will be independent of what + * the bounds of the items were prior to the layout so two pre-draw passes will + * be made. This is necessary because after the layout takes place, some views that + * were visible before the layout may now be off bounds but a reference to these + * views is required so the animation completes as intended. + * + * 3. The first predraw pass will set the bounds of all the visible items to + * their original location before the layout took place and then force another + * layout. Since the bounds of the cells cannot be set directly, the method + * setSelectionFromTop can be used to achieve a very similar effect. + * 4. The expanding view's bounds are animated to what the final values should be + * from the original bounds. + * 5. The bounds above the expanding view are animated upwards while the bounds + * below the expanding view are animated downwards. + * 6. The extra text is faded in as its contents become visible throughout the + * animation process. + * + * It is important to note that the listview is disabled during the animation + * because the scrolling behaviour is unpredictable if the bounds of the items + * within the listview are not constant during the scroll. + */ + + private void expandView(final View view) { + final ExpandableListItem viewObject = (ExpandableListItem)getItemAtPosition(getPositionForView + (view)); + + /* Store the original top and bottom bounds of all the cells.*/ + final int oldTop = view.getTop(); + final int oldBottom = view.getBottom(); + + final HashMap oldCoordinates = new HashMap(); + + int childCount = getChildCount(); + for (int i = 0; i < childCount; i++) { + View v = getChildAt(i); + v.setHasTransientState(true); + oldCoordinates.put(v, new int[] {v.getTop(), v.getBottom()}); + } + + /* Update the layout so the extra content becomes visible.*/ + final View expandingLayout = view.findViewById(R.id.expanding_layout); + expandingLayout.setVisibility(View.VISIBLE); + + /* Add an onPreDraw Listener to the listview. onPreDraw will get invoked after onLayout + * and onMeasure have run but before anything has been drawn. This + * means that the final post layout properties for all the items have already been + * determined, but still have not been rendered onto the screen.*/ + final ViewTreeObserver observer = getViewTreeObserver(); + observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { + + @Override + public boolean onPreDraw() { + /* Determine if this is the first or second pass.*/ + if (!mShouldRemoveObserver) { + mShouldRemoveObserver = true; + + /* Calculate what the parameters should be for setSelectionFromTop. + * The ListView must be offset in a way, such that after the animation + * takes place, all the cells that remain visible are rendered completely + * by the ListView.*/ + int newTop = view.getTop(); + int newBottom = view.getBottom(); + + int newHeight = newBottom - newTop; + int oldHeight = oldBottom - oldTop; + int delta = newHeight - oldHeight; + + mTranslate = getTopAndBottomTranslations(oldTop, oldBottom, delta, true); + + int currentTop = view.getTop(); + int futureTop = oldTop - mTranslate[0]; + + int firstChildStartTop = getChildAt(0).getTop(); + int firstVisiblePosition = getFirstVisiblePosition(); + int deltaTop = currentTop - futureTop; + + int i; + int childCount = getChildCount(); + for (i = 0; i < childCount; i++) { + View v = getChildAt(i); + int height = v.getBottom() - Math.max(0, v.getTop()); + if (deltaTop - height > 0) { + firstVisiblePosition++; + deltaTop -= height; + } else { + break; + } + } + + if (i > 0) { + firstChildStartTop = 0; + } + + setSelectionFromTop(firstVisiblePosition, firstChildStartTop - deltaTop); + + /* Request another layout to update the layout parameters of the cells.*/ + requestLayout(); + + /* Return false such that the ListView does not redraw its contents on + * this layout but only updates all the parameters associated with its + * children.*/ + return false; + } + + /* Remove the predraw listener so this method does not keep getting called. */ + mShouldRemoveObserver = false; + observer.removeOnPreDrawListener(this); + + int yTranslateTop = mTranslate[0]; + int yTranslateBottom = mTranslate[1]; + + ArrayList animations = new ArrayList(); + + int index = indexOfChild(view); + + /* Loop through all the views that were on the screen before the cell was + * expanded. Some cells will still be children of the ListView while + * others will not. The cells that remain children of the ListView + * simply have their bounds animated appropriately. The cells that are no + * longer children of the ListView also have their bounds animated, but + * must also be added to a list of views which will be drawn in dispatchDraw.*/ + for (View v: oldCoordinates.keySet()) { + int[] old = oldCoordinates.get(v); + v.setTop(old[0]); + v.setBottom(old[1]); + if (v.getParent() == null) { + mViewsToDraw.add(v); + int delta = old[0] < oldTop ? -yTranslateTop : yTranslateBottom; + animations.add(getAnimation(v, delta, delta)); + } else { + int i = indexOfChild(v); + if (v != view) { + int delta = i > index ? yTranslateBottom : -yTranslateTop; + animations.add(getAnimation(v, delta, delta)); + } + v.setHasTransientState(false); + } + } + + /* Adds animation for expanding the cell that was clicked. */ + animations.add(getAnimation(view, -yTranslateTop, yTranslateBottom)); + + /* Adds an animation for fading in the extra content. */ + animations.add(ObjectAnimator.ofFloat(view.findViewById(R.id.expanding_layout), + View.ALPHA, 0, 1)); + + /* Disabled the ListView for the duration of the animation.*/ + setEnabled(false); + setClickable(false); + + /* Play all the animations created above together at the same time. */ + AnimatorSet s = new AnimatorSet(); + s.playTogether(animations); + s.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + viewObject.setExpanded(true); + setEnabled(true); + setClickable(true); + if (mViewsToDraw.size() > 0) { + for (View v : mViewsToDraw) { + v.setHasTransientState(false); + } + } + mViewsToDraw.clear(); + } + }); + s.start(); + return true; + } + }); + } + + /** + * By overriding dispatchDraw, we can draw the cells that disappear during the + * expansion process. When the cell expands, some items below or above the expanding + * cell may be moved off screen and are thus no longer children of the ListView's + * layout. By storing a reference to these views prior to the layout, and + * guaranteeing that these cells do not get recycled, the cells can be drawn + * directly onto the canvas during the animation process. After the animation + * completes, the references to the extra views can then be discarded. + */ + @Override + protected void dispatchDraw(Canvas canvas) { + super.dispatchDraw(canvas); + + if (mViewsToDraw.size() == 0) { + return; + } + + for (View v: mViewsToDraw) { + canvas.translate(0, v.getTop()); + v.draw(canvas); + canvas.translate(0, -v.getTop()); + } + } + + /** + * This method collapses the view that was clicked and animates all the views + * around it to close around the collapsing view. There are several steps required + * to do this which are outlined below. + * + * 1. Update the layout parameters of the view clicked so as to minimize its height + * to the original collapsed (default) state. + * 2. After invoking a layout, the listview will shift all the cells so as to display + * them most efficiently. Therefore, during the first predraw pass, the listview + * must be offset by some amount such that given the custom bound change upon + * collapse, all the cells that need to be on the screen after the layout + * are rendered by the listview. + * 3. On the second predraw pass, all the items are first returned to their original + * location (before the first layout). + * 4. The collapsing view's bounds are animated to what the final values should be. + * 5. The bounds above the collapsing view are animated downwards while the bounds + * below the collapsing view are animated upwards. + * 6. The extra text is faded out as its contents become visible throughout the + * animation process. + */ + + private void collapseView(final View view) { + final ExpandableListItem viewObject = (ExpandableListItem)getItemAtPosition + (getPositionForView(view)); + + /* Store the original top and bottom bounds of all the cells.*/ + final int oldTop = view.getTop(); + final int oldBottom = view.getBottom(); + + final HashMap oldCoordinates = new HashMap(); + + int childCount = getChildCount(); + for (int i = 0; i < childCount; i++) { + View v = getChildAt(i); + v.setHasTransientState(true); + oldCoordinates.put(v, new int [] {v.getTop(), v.getBottom()}); + } + + /* Update the layout so the extra content becomes invisible.*/ + view.setLayoutParams(new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT, + viewObject.getCollapsedHeight())); + + /* Add an onPreDraw listener. */ + final ViewTreeObserver observer = getViewTreeObserver(); + observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { + + @Override + public boolean onPreDraw() { + + if (!mShouldRemoveObserver) { + /*Same as for expandingView, the parameters for setSelectionFromTop must + * be determined such that the necessary cells of the ListView are rendered + * and added to it.*/ + mShouldRemoveObserver = true; + + int newTop = view.getTop(); + int newBottom = view.getBottom(); + + int newHeight = newBottom - newTop; + int oldHeight = oldBottom - oldTop; + int deltaHeight = oldHeight - newHeight; + + mTranslate = getTopAndBottomTranslations(oldTop, oldBottom, deltaHeight, false); + + int currentTop = view.getTop(); + int futureTop = oldTop + mTranslate[0]; + + int firstChildStartTop = getChildAt(0).getTop(); + int firstVisiblePosition = getFirstVisiblePosition(); + int deltaTop = currentTop - futureTop; + + int i; + int childCount = getChildCount(); + for (i = 0; i < childCount; i++) { + View v = getChildAt(i); + int height = v.getBottom() - Math.max(0, v.getTop()); + if (deltaTop - height > 0) { + firstVisiblePosition++; + deltaTop -= height; + } else { + break; + } + } + + if (i > 0) { + firstChildStartTop = 0; + } + + setSelectionFromTop(firstVisiblePosition, firstChildStartTop - deltaTop); + + requestLayout(); + + return false; + } + + mShouldRemoveObserver = false; + observer.removeOnPreDrawListener(this); + + int yTranslateTop = mTranslate[0]; + int yTranslateBottom = mTranslate[1]; + + int index = indexOfChild(view); + int childCount = getChildCount(); + for (int i = 0; i < childCount; i++) { + View v = getChildAt(i); + int [] old = oldCoordinates.get(v); + if (old != null) { + /* If the cell was present in the ListView before the collapse and + * after the collapse then the bounds are reset to their old values.*/ + v.setTop(old[0]); + v.setBottom(old[1]); + v.setHasTransientState(false); + } else { + /* If the cell is present in the ListView after the collapse but + * not before the collapse then the bounds are calculated using + * the bottom and top translation of the collapsing cell.*/ + int delta = i > index ? yTranslateBottom : -yTranslateTop; + v.setTop(v.getTop() + delta); + v.setBottom(v.getBottom() + delta); + } + } + + final View expandingLayout = view.findViewById (R.id.expanding_layout); + + /* Animates all the cells present on the screen after the collapse. */ + ArrayList animations = new ArrayList(); + for (int i = 0; i < childCount; i++) { + View v = getChildAt(i); + if (v != view) { + float diff = i > index ? -yTranslateBottom : yTranslateTop; + animations.add(getAnimation(v, diff, diff)); + } + } + + + /* Adds animation for collapsing the cell that was clicked. */ + animations.add(getAnimation(view, yTranslateTop, -yTranslateBottom)); + + /* Adds an animation for fading out the extra content. */ + animations.add(ObjectAnimator.ofFloat(expandingLayout, View.ALPHA, 1, 0)); + + /* Disabled the ListView for the duration of the animation.*/ + setEnabled(false); + setClickable(false); + + /* Play all the animations created above together at the same time. */ + AnimatorSet s = new AnimatorSet(); + s.playTogether(animations); + s.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + expandingLayout.setVisibility(View.GONE); + view.setLayoutParams(new AbsListView.LayoutParams(AbsListView + .LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.WRAP_CONTENT)); + viewObject.setExpanded(false); + setEnabled(true); + setClickable(true); + /* Note that alpha must be set back to 1 in case this view is reused + * by a cell that was expanded, but not yet collapsed, so its state + * should persist in an expanded state with the extra content visible.*/ + expandingLayout.setAlpha(1); + } + }); + s.start(); + + return true; + } + }); + } + + /** + * This method takes some view and the values by which its top and bottom bounds + * should be changed by. Given these params, an animation which will animate + * these bound changes is created and returned. + */ + private Animator getAnimation(final View view, float translateTop, float translateBottom) { + + int top = view.getTop(); + int bottom = view.getBottom(); + + int endTop = (int)(top + translateTop); + int endBottom = (int)(bottom + translateBottom); + + PropertyValuesHolder translationTop = PropertyValuesHolder.ofInt("top", top, endTop); + PropertyValuesHolder translationBottom = PropertyValuesHolder.ofInt("bottom", bottom, + endBottom); + + return ObjectAnimator.ofPropertyValuesHolder(view, translationTop, translationBottom); + } +} diff --git a/samples/devbytes/animation/ListViewExpandingCells/src/com/example/android/expandingcells/OnSizeChangedListener.java b/samples/devbytes/animation/ListViewExpandingCells/src/com/example/android/expandingcells/OnSizeChangedListener.java new file mode 100644 index 000000000..ec5195071 --- /dev/null +++ b/samples/devbytes/animation/ListViewExpandingCells/src/com/example/android/expandingcells/OnSizeChangedListener.java @@ -0,0 +1,25 @@ +/* + * 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.expandingcells; + +/** + * A listener used to update the list data object when the corresponding expanding + * layout experiences a size change. + */ +public interface OnSizeChangedListener { + public void onSizeChanged(int newHeight); +}