[笔记] ListView项展开动画例子

代码来源: [Android源码]DeskClock/com.android.deskclock.AlarmClockFragment
源码版本: 4.4.2

/**
 * Expands the alarm for editing.
 *
 * @param itemHolder The item holder instance.
 */
private void expandAlarm(final ItemHolder itemHolder, boolean animate) {
    mExpanded.add(itemHolder.alarm.id);
    bindExpandArea(itemHolder, itemHolder.alarm);
    // Scroll the view to make sure it is fully viewed
    mScrollAlarmId = itemHolder.alarm.id;

    // Save the starting height so we can animate from this value.
    final int startingHeight = itemHolder.alarmItem.getHeight();

    // Set the expand area to visible so we can measure the height to animate to.
    itemHolder.alarmItem.setBackgroundColor(mBackgroundColorExpanded);
    itemHolder.expandArea.setVisibility(View.VISIBLE);

    if (!animate) {
        // Set the "end" layout and don't do the animation.
        itemHolder.arrow.setRotation(180);
        // We need to translate the hairline up, so the height of the collapseArea
        // needs to be measured to know how high to translate it.
        final ViewTreeObserver observer = mAlarmsList.getViewTreeObserver();
        observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @Override
            public boolean onPreDraw() {
                // We don't want to continue getting called for every listview drawing.
                if (observer.isAlive()) {
                    observer.removeOnPreDrawListener(this);
                }
                int hairlineHeight = itemHolder.hairLine.getHeight();
                int collapseHeight =
                        itemHolder.collapseExpandArea.getHeight() - hairlineHeight;
                itemHolder.hairLine.setTranslationY(-collapseHeight);
                return true;
            }
        });
        return;
    }

    // Add an onPreDrawListener, which gets called after measurement but before the draw.
    // This way we can check the height we need to animate to before any drawing.
    // Note the series of events:
    //  * expandArea is set to VISIBLE, which causes a layout pass
    //  * the view is measured, and our onPreDrawListener is called
    //  * we set up the animation using the start and end values.
    //  * the height is set back to the starting point so it can be animated down.
    //  * request another layout pass.
    //  * return false so that onDraw() is not called for the single frame before
    //    the animations have started.
    final ViewTreeObserver observer = mAlarmsList.getViewTreeObserver();
    observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
        @Override
        public boolean onPreDraw() {
            // We don't want to continue getting called for every listview drawing.
            if (observer.isAlive()) {
                observer.removeOnPreDrawListener(this);
            }
            // Calculate some values to help with the animation.
            final int endingHeight = itemHolder.alarmItem.getHeight();
            final int distance = endingHeight - startingHeight;
            final int collapseHeight = itemHolder.collapseExpandArea.getHeight();
            int hairlineHeight = itemHolder.hairLine.getHeight();
            final int hairlineDistance = collapseHeight - hairlineHeight;

            // Set the height back to the start state of the animation.
            itemHolder.alarmItem.getLayoutParams().height = startingHeight;
            // To allow the expandArea to glide in with the expansion animation, set a
            // negative top margin, which will animate down to a margin of 0 as the height
            // is increased.
            // Note that we need to maintain the bottom margin as a fixed value (instead of
            // just using a listview, to allow for a flatter hierarchy) to fit the bottom
            // bar underneath.
            FrameLayout.LayoutParams expandParams = (FrameLayout.LayoutParams)
                    itemHolder.expandArea.getLayoutParams();
            expandParams.setMargins(0, -distance, 0, collapseHeight);
            itemHolder.alarmItem.requestLayout();

            // Set up the animator to animate the expansion.
            ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f)
                    .setDuration(EXPAND_DURATION);
            animator.setInterpolator(mExpandInterpolator);
            animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animator) {
                    Float value = (Float) animator.getAnimatedValue();

                    // For each value from 0 to 1, animate the various parts of the layout.
                    itemHolder.alarmItem.getLayoutParams().height =
                            (int) (value * distance + startingHeight);
                    FrameLayout.LayoutParams expandParams = (FrameLayout.LayoutParams)
                            itemHolder.expandArea.getLayoutParams();
                    expandParams.setMargins(
                            0, (int) -((1 - value) * distance), 0, collapseHeight);
                    itemHolder.arrow.setRotation(180 * value);
                    itemHolder.hairLine.setTranslationY(-hairlineDistance * value);
                    itemHolder.summary.setAlpha(1 - value);

                    itemHolder.alarmItem.requestLayout();
                }
            });
            // Set everything to their final values when the animation's done.
            animator.addListener(new AnimatorListener() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    // Set it back to wrap content since we'd explicitly set the height.
                    itemHolder.alarmItem.getLayoutParams().height =
                            LayoutParams.WRAP_CONTENT;
                    itemHolder.arrow.setRotation(180);
                    itemHolder.hairLine.setTranslationY(-hairlineDistance);
                    itemHolder.summary.setVisibility(View.GONE);
                }

                @Override
                public void onAnimationCancel(Animator animation) {
                    // TODO we may have to deal with cancelations of the animation.
                }

                @Override
                public void onAnimationRepeat(Animator animation) { }
                @Override
                public void onAnimationStart(Animator animation) { }
            });
            animator.start();

            // Return false so this draw does not occur to prevent the final frame from
            // being drawn for the single frame before the animations start.
            return false;
        }
    });
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个使用ListView展示SQLite数据库中数据的例子: 1. 首先创建一个数据库帮助类,用来执行数据库操作: ```java public class DBHelper extends SQLiteOpenHelper { private static final String DATABASE_NAME = "mydb.db"; private static final int DATABASE_VERSION = 1; public DBHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE IF NOT EXISTS person(_id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR, age INTEGER)"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS person"); onCreate(db); } } ``` 2. 在需要展示数据的Activity中,创建ListView并从数据库中查询数据: ```java public class MainActivity extends AppCompatActivity { private ListView listView; private DBHelper dbHelper; private SQLiteDatabase db; private Cursor cursor; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listView = findViewById(R.id.listView); dbHelper = new DBHelper(this); db = dbHelper.getWritableDatabase(); cursor = db.rawQuery("SELECT * FROM person", null); SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2, cursor, new String[]{"name", "age"}, new int[]{android.R.id.text1, android.R.id.text2}); listView.setAdapter(adapter); } } ``` 3. 在XML布局文件中创建ListView: ```xml <ListView android:id="@+id/listView" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 以上代码中,我们创建了一个名为person的数据表,其中有三个字段:_id、name、age,我们在MainActivty中从person表中查询所有的数据,并使用SimpleCursorAdapter将数据绑定在ListView上展示出来。 注意,如果你想运行这个例子,需要在AndroidManifest.xml文件中加入写数据库的权限: ```xml <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值