Android仿淘宝头条垂直滚动,垂直走马灯,公告
16lz
2021-01-26
今天看了淘宝头条的的滚动,感觉用户体验非常好,然后在就github上找到了一个,
github:https://github.com/gongwen/MarqueeViewLibrary
效果图如下:
实现方式通过MarqueeFactory来提供各种样式的跑马灯View, 支持自定义跑马灯ItemView。
1.首先在build.gradle中增加:
compile ‘com.gongwen:marqueelibrary:1.0.4’
2.MainActivity的xml文件中:
<?xml version="1.0" encoding="utf-8"?>"http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.example.administrator.marqueeviewdemo.MainActivity"> <com.gongwen.marqueen.MarqueeView android:id="@+id/marqueeView1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:background="#88dddddd"/> <com.gongwen.marqueen.MarqueeView android:id="@+id/marqueeView2" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:background="#88dddddd" app:marqueeAnimDuration="2000" app:marqueeAnimIn="@anim/right_in" app:marqueeAnimOut="@anim/left_out" app:marqueeInterval="2500"/> <com.gongwen.marqueen.MarqueeView android:id="@+id/marqueeView3" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:background="#88dddddd"/> <com.gongwen.marqueen.MarqueeView android:id="@+id/marqueeView4" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:background="#88dddddd"/> <com.gongwen.marqueen.MarqueeView android:id="@+id/marqueeView5" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:background="#88dddddd"/>
3.MainActivity中:
public class MainActivity extends AppCompatActivity { private MarqueeView marqueeView1, marqueeView2, marqueeView3, marqueeView4, marqueeView5; private List list; private WeakHandler mHandler = new WeakHandler(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); list = new ArrayList<>(); list.add("人生若只如初见,何事秋风悲画扇"); list.add("等闲变却故人心,却道故人心易变"); list.add("骊山语罢清宵半,泪雨零铃终不怨"); list.add("何如薄幸锦衣郎,比翼连枝当日愿"); marqueeView1 = (MarqueeView) findViewById(R.id.marqueeView1); marqueeView2 = (MarqueeView) findViewById(R.id.marqueeView2); marqueeView3 = (MarqueeView) findViewById(R.id.marqueeView3); marqueeView4 = (MarqueeView) findViewById(R.id.marqueeView4); marqueeView5 = (MarqueeView) findViewById(R.id.marqueeView5); //文字向上翻转 MarqueeFactory marqueeFactory1 = new NoticeMF(this); //MarqueeView设置Factory marqueeView1.setMarqueeFactory(marqueeFactory1); //开始翻转 marqueeView1.startFlipping(); //设置item的监听 marqueeFactory1.setOnItemClickListener(new MarqueeFactory.OnItemClickListener() { @Override public void onItemClickListener(MarqueeFactory.ViewHolder holder) { Toast.makeText(MainActivity.this, holder.data, Toast.LENGTH_SHORT).show(); } }); //设置数据 marqueeFactory1.setData(list); //文字向左翻转 final MarqueeFactory marqueeFactory2 = new NoticeMF(this); //MarqueeView设置Factory marqueeView2.setMarqueeFactory(marqueeFactory2); //开始翻转 marqueeView2.startFlipping(); //设置item的监听 marqueeFactory2.setOnItemClickListener(new MarqueeFactory.OnItemClickListener() { @Override public void onItemClickListener(MarqueeFactory.ViewHolder holder) { Toast.makeText(MainActivity.this, holder.data, Toast.LENGTH_SHORT).show(); } }); //设置数据 marqueeFactory2.setData(list); //文字向右翻转 MarqueeFactory marqueeFactory3 = new NoticeMF(this); //设置监听 marqueeFactory3.setOnItemClickListener(new MarqueeFactory.OnItemClickListener() { @Override public void onItemClickListener(MarqueeFactory.ViewHolder holder) { Toast.makeText(MainActivity.this, holder.data, Toast.LENGTH_SHORT).show(); } }); //设置数据 marqueeFactory3.setData(list); //MarqueeView设置Factory marqueeView3.setMarqueeFactory(marqueeFactory3); //设置进入退出的动画 marqueeView3.setAnimInAndOut(R.anim.left_in, R.anim.right_out); //动画执行时间 marqueeView3.setAnimDuration(2000); //翻页时间间隔 marqueeView3.setInterval(2500); marqueeView3.setAnimateFirstView(true); //直接调用startFlipping,setAnimateFirstView并没有生效 //marqueeView3.startFlipping(); mHandler.post(new Runnable() { @Override public void run() { //开始翻转 marqueeView3.startFlipping(); } }); //文字向下翻转 MarqueeFactory marqueeFactory4 = new NoticeMF(this); //设置监听 marqueeFactory4.setOnItemClickListener(new MarqueeFactory.OnItemClickListener() { @Override public void onItemClickListener(MarqueeFactory.ViewHolder holder) { Toast.makeText(MainActivity.this, holder.data, Toast.LENGTH_SHORT).show(); } }); //设置数据 marqueeFactory4.setData(list); //设置进入退出的动画 marqueeView4.setAnimInAndOut(R.anim.top_in, R.anim.bottom_out); //MarqueeView设置Factory marqueeView4.setMarqueeFactory(marqueeFactory4); //开始翻转 marqueeView4.startFlipping(); //设置多行布局 List dataList = new ArrayList<>(); for (int i = 0; i < 5; i++) { dataList.add(new MyData("标题 " + i, "内容 " + i, "时间 " + i)); } MarqueeFactory marqueeFactory5 = new ComplexViewMF(this); marqueeFactory5.setData(dataList); marqueeView5.setAnimInAndOut(R.anim.top_in, R.anim.bottom_out); //MarqueeView设置Factory marqueeView5.setMarqueeFactory(marqueeFactory5); //开始翻转 marqueeView5.startFlipping(); } @Override protected void onStart() { super.onStart(); marqueeView1.startFlipping(); marqueeView2.startFlipping(); marqueeView3.startFlipping(); marqueeView4.startFlipping(); marqueeView5.startFlipping(); } @Override protected void onStop() { super.onStop(); marqueeView1.stopFlipping(); marqueeView2.stopFlipping(); marqueeView3.stopFlipping(); marqueeView4.stopFlipping(); marqueeView5.stopFlipping(); }}
4.NoticeMF中:
public class NoticeMF extends MarqueeFactory<TextView, String> { private LayoutInflater inflater; public NoticeMF(Context mContext) { super(mContext); inflater = LayoutInflater.from(mContext); } @Override public TextView generateMarqueeItemView(String data) { TextView mView = (TextView) inflater.inflate(R.layout.notice_item, null); mView.setText(data); return mView; }}
5.notice_item中:
<?xml version="1.0" encoding="utf-8"?><TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:ellipsize="end" android:maxLines="1" android:padding="15dp" android:textSize="15sp" />
6.MyData中:
public class MyData { private String title; private String body; private String time; public MyData(String title, String body, String time) { this.title = title; this.body = body; this.time = time; } public MyData() { } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getBody() { return body; } public void setBody(String body) { this.body = body; } public String getTime() { return time; } public void setTime(String time) { this.time = time; }}
7.ComplexViewMF中:
public class ComplexViewMF extends MarqueeFactory<RelativeLayout, MyData> { private LayoutInflater inflater; public ComplexViewMF(Context mContext) { super(mContext); inflater = LayoutInflater.from(mContext); } @Override public RelativeLayout generateMarqueeItemView(MyData data) { RelativeLayout mView = (RelativeLayout) inflater.inflate(R.layout.complex_view, null); ((TextView) mView.findViewById(R.id.title)).setText(data.getTitle()); ((TextView) mView.findViewById(R.id.body)).setText(data.getBody()); ((TextView) mView.findViewById(R.id.time)).setText(data.getTime()); return mView; }}
8.complex_view中:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="10dp"> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="标题" /> <TextView android:id="@+id/body" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/title" android:layout_marginTop="10dp" android:text="副标题" /> <TextView android:id="@+id/time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:text="2016-12-20 18:18" />RelativeLayout>
9.WeakHandler中:
/* * Copyright (c) 2014 Badoo Trading Limited * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * Portions of documentation in this code are modifications based on work created and * shared by Android Open Source Project and used according to terms described in the * Apache License, Version 2.0 */package com.example.administrator.marqueeviewdemo;import android.os.Handler;import android.os.Looper;import android.os.Message;import android.support.annotation.NonNull;import android.support.annotation.Nullable;import android.support.annotation.VisibleForTesting;import java.lang.ref.WeakReference;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;/** * Memory safer implementation of android.os.Handler * * Original implementation of Handlers always keeps hard reference to handler in queue of execution. * If you create anonymous handler and post delayed message into it, it will keep all parent class * for that time in memory even if it could be cleaned. * * This implementation is trickier, it will keep WeakReferences to runnables and messages, * and GC could collect them once WeakHandler instance is not referenced any more * * * @see Handler * * Created by Dmytro Voronkevych on 17/06/2014. */@SuppressWarnings("unused")public class WeakHandler { private final Handler.Callback mCallback; // hard reference to Callback. We need to keep callback in memory private final ExecHandler mExec; private Lock mLock = new ReentrantLock(); @SuppressWarnings("ConstantConditions") @VisibleForTesting final ChainedRef mRunnables = new ChainedRef(mLock, null); /** * Default constructor associates this handler with the {@link Looper} for the * current thread. * * If this thread does not have a looper, this handler won't be able to receive messages * so an exception is thrown. */ public WeakHandler() { mCallback = null; mExec = new ExecHandler(); } /** * Constructor associates this handler with the {@link Looper} for the * current thread and takes a callback interface in which you can handle * messages. * * If this thread does not have a looper, this handler won't be able to receive messages * so an exception is thrown. * * @param callback The callback interface in which to handle messages, or null. */ public WeakHandler(@Nullable Handler.Callback callback) { mCallback = callback; // Hard referencing body mExec = new ExecHandler(new WeakReference<>(callback)); // Weak referencing inside ExecHandler } /** * Use the provided {@link Looper} instead of the default one. * * @param looper The looper, must not be null. */ public WeakHandler(@NonNull Looper looper) { mCallback = null; mExec = new ExecHandler(looper); } /** * Use the provided {@link Looper} instead of the default one and take a callback * interface in which to handle messages. * * @param looper The looper, must not be null. * @param callback The callback interface in which to handle messages, or null. */ public WeakHandler(@NonNull Looper looper, @NonNull Handler.Callback callback) { mCallback = callback; mExec = new ExecHandler(looper, new WeakReference<>(callback)); } /** * Causes the Runnable r to be added to the message queue. * The runnable will be run on the thread to which this handler is * attached. * * @param r The Runnable that will be executed. * * @return Returns true if the Runnable was successfully placed in to the * message queue. Returns false on failure, usually because the * looper processing the message queue is exiting. */ public final boolean post(@NonNull Runnable r) { return mExec.post(wrapRunnable(r)); } /** * Causes the Runnable r to be added to the message queue, to be run * at a specific time given by uptimeMillis. * The time-base is {@link android.os.SystemClock#uptimeMillis}. * The runnable will be run on the thread to which this handler is attached. * * @param r The Runnable that will be executed. * @param uptimeMillis The absolute time at which the callback should run, * using the {@link android.os.SystemClock#uptimeMillis} time-base. * * @return Returns true if the Runnable was successfully placed in to the * message queue. Returns false on failure, usually because the * looper processing the message queue is exiting. Note that a * result of true does not mean the Runnable will be processed -- if * the looper is quit before the delivery time of the message * occurs then the message will be dropped. */ public final boolean postAtTime(@NonNull Runnable r, long uptimeMillis) { return mExec.postAtTime(wrapRunnable(r), uptimeMillis); } /** * Causes the Runnable r to be added to the message queue, to be run * at a specific time given by uptimeMillis. * The time-base is {@link android.os.SystemClock#uptimeMillis}. * The runnable will be run on the thread to which this handler is attached. * * @param r The Runnable that will be executed. * @param uptimeMillis The absolute time at which the callback should run, * using the {@link android.os.SystemClock#uptimeMillis} time-base. * * @return Returns true if the Runnable was successfully placed in to the * message queue. Returns false on failure, usually because the * looper processing the message queue is exiting. Note that a * result of true does not mean the Runnable will be processed -- if * the looper is quit before the delivery time of the message * occurs then the message will be dropped. * * @see android.os.SystemClock#uptimeMillis */ public final boolean postAtTime(Runnable r, Object token, long uptimeMillis) { return mExec.postAtTime(wrapRunnable(r), token, uptimeMillis); } /** * Causes the Runnable r to be added to the message queue, to be run * after the specified amount of time elapses. * The runnable will be run on the thread to which this handler * is attached. * * @param r The Runnable that will be executed. * @param delayMillis The delay (in milliseconds) until the Runnable * will be executed. * * @return Returns true if the Runnable was successfully placed in to the * message queue. Returns false on failure, usually because the * looper processing the message queue is exiting. Note that a * result of true does not mean the Runnable will be processed -- * if the looper is quit before the delivery time of the message * occurs then the message will be dropped. */ public final boolean postDelayed(Runnable r, long delayMillis) { return mExec.postDelayed(wrapRunnable(r), delayMillis); } /** * Posts a message to an object that implements Runnable. * Causes the Runnable r to executed on the next iteration through the * message queue. The runnable will be run on the thread to which this * handler is attached. * This method is only for use in very special circumstances -- it * can easily starve the message queue, cause ordering problems, or have * other unexpected side-effects. * * @param r The Runnable that will be executed. * * @return Returns true if the message was successfully placed in to the * message queue. Returns false on failure, usually because the * looper processing the message queue is exiting. */ public final boolean postAtFrontOfQueue(Runnable r) { return mExec.postAtFrontOfQueue(wrapRunnable(r)); } /** * Remove any pending posts of Runnable r that are in the message queue. */ public final void removeCallbacks(Runnable r) { final WeakRunnable runnable = mRunnables.remove(r); if (runnable != null) { mExec.removeCallbacks(runnable); } } /** * Remove any pending posts of Runnable r with Object * token that are in the message queue. If token is null, * all callbacks will be removed. */ public final void removeCallbacks(Runnable r, Object token) { final WeakRunnable runnable = mRunnables.remove(r); if (runnable != null) { mExec.removeCallbacks(runnable, token); } } /** * Pushes a message onto the end of the message queue after all pending messages * before the current time. It will be received in callback, * in the thread attached to this handler. * * @return Returns true if the message was successfully placed in to the * message queue. Returns false on failure, usually because the * looper processing the message queue is exiting. */ public final boolean sendMessage(Message msg) { return mExec.sendMessage(msg); } /** * Sends a Message containing only the what value. * * @return Returns true if the message was successfully placed in to the * message queue. Returns false on failure, usually because the * looper processing the message queue is exiting. */ public final boolean sendEmptyMessage(int what) { return mExec.sendEmptyMessage(what); } /** * Sends a Message containing only the what value, to be delivered * after the specified amount of time elapses. * @see #sendMessageDelayed(Message, long) * * @return Returns true if the message was successfully placed in to the * message queue. Returns false on failure, usually because the * looper processing the message queue is exiting. */ public final boolean sendEmptyMessageDelayed(int what, long delayMillis) { return mExec.sendEmptyMessageDelayed(what, delayMillis); } /** * Sends a Message containing only the what value, to be delivered * at a specific time. * @see #sendMessageAtTime(Message, long) * * @return Returns true if the message was successfully placed in to the * message queue. Returns false on failure, usually because the * looper processing the message queue is exiting. */ public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) { return mExec.sendEmptyMessageAtTime(what, uptimeMillis); } /** * Enqueue a message into the message queue after all pending messages * before (current time + delayMillis). You will receive it in * callback, in the thread attached to this handler. * * @return Returns true if the message was successfully placed in to the * message queue. Returns false on failure, usually because the * looper processing the message queue is exiting. Note that a * result of true does not mean the message will be processed -- if * the looper is quit before the delivery time of the message * occurs then the message will be dropped. */ public final boolean sendMessageDelayed(Message msg, long delayMillis) { return mExec.sendMessageDelayed(msg, delayMillis); } /** * Enqueue a message into the message queue after all pending messages * before the absolute time (in milliseconds) uptimeMillis. * The time-base is {@link android.os.SystemClock#uptimeMillis}. * You will receive it in callback, in the thread attached * to this handler. * * @param uptimeMillis The absolute time at which the message should be * delivered, using the * {@link android.os.SystemClock#uptimeMillis} time-base. * * @return Returns true if the message was successfully placed in to the * message queue. Returns false on failure, usually because the * looper processing the message queue is exiting. Note that a * result of true does not mean the message will be processed -- if * the looper is quit before the delivery time of the message * occurs then the message will be dropped. */ public boolean sendMessageAtTime(Message msg, long uptimeMillis) { return mExec.sendMessageAtTime(msg, uptimeMillis); } /** * Enqueue a message at the front of the message queue, to be processed on * the next iteration of the message loop. You will receive it in * callback, in the thread attached to this handler. * This method is only for use in very special circumstances -- it * can easily starve the message queue, cause ordering problems, or have * other unexpected side-effects. * * @return Returns true if the message was successfully placed in to the * message queue. Returns false on failure, usually because the * looper processing the message queue is exiting. */ public final boolean sendMessageAtFrontOfQueue(Message msg) { return mExec.sendMessageAtFrontOfQueue(msg); } /** * Remove any pending posts of messages with code 'what' that are in the * message queue. */ public final void removeMessages(int what) { mExec.removeMessages(what); } /** * Remove any pending posts of messages with code 'what' and whose obj is * 'object' that are in the message queue. If object is null, * all messages will be removed. */ public final void removeMessages(int what, Object object) { mExec.removeMessages(what, object); } /** * Remove any pending posts of callbacks and sent messages whose * obj is token. If token is null, * all callbacks and messages will be removed. */ public final void removeCallbacksAndMessages(Object token) { mExec.removeCallbacksAndMessages(token); } /** * Check if there are any pending posts of messages with code 'what' in * the message queue. */ public final boolean hasMessages(int what) { return mExec.hasMessages(what); } /** * Check if there are any pending posts of messages with code 'what' and * whose obj is 'object' in the message queue. */ public final boolean hasMessages(int what, Object object) { return mExec.hasMessages(what, object); } public final Looper getLooper() { return mExec.getLooper(); } private WeakRunnable wrapRunnable(@NonNull Runnable r) { //noinspection ConstantConditions if (r == null) { throw new NullPointerException("Runnable can't be null"); } final ChainedRef hardRef = new ChainedRef(mLock, r); mRunnables.insertAfter(hardRef); return hardRef.wrapper; } private static class ExecHandler extends Handler { private final WeakReference mCallback; ExecHandler() { mCallback = null; } ExecHandler(WeakReference callback) { mCallback = callback; } ExecHandler(Looper looper) { super(looper); mCallback = null; } ExecHandler(Looper looper, WeakReference callback) { super(looper); mCallback = callback; } @Override public void handleMessage(@NonNull Message msg) { if (mCallback == null) { return; } final Callback callback = mCallback.get(); if (callback == null) { // Already disposed return; } callback.handleMessage(msg); } } static class WeakRunnable implements Runnable { private final WeakReference mDelegate; private final WeakReference mReference; WeakRunnable(WeakReference delegate, WeakReference reference) { mDelegate = delegate; mReference = reference; } @Override public void run() { final Runnable delegate = mDelegate.get(); final ChainedRef reference = mReference.get(); if (reference != null) { reference.remove(); } if (delegate != null) { delegate.run(); } } } static class ChainedRef { @Nullable ChainedRef next; @Nullable ChainedRef prev; @NonNull final Runnable runnable; @NonNull final WeakRunnable wrapper; @NonNull Lock lock; public ChainedRef(@NonNull Lock lock, @NonNull Runnable r) { this.runnable = r; this.lock = lock; this.wrapper = new WeakRunnable(new WeakReference<>(r), new WeakReference<>(this)); } public WeakRunnable remove() { lock.lock(); try { if (prev != null) { prev.next = next; } if (next != null) { next.prev = prev; } prev = null; next = null; } finally { lock.unlock(); } return wrapper; } public void insertAfter(@NonNull ChainedRef candidate) { lock.lock(); try { if (this.next != null) { this.next.prev = candidate; } candidate.next = this.next; this.next = candidate; candidate.prev = this; } finally { lock.unlock(); } } @Nullable public WeakRunnable remove(Runnable obj) { lock.lock(); try { ChainedRef curr = this.next; // Skipping head while (curr != null) { if (curr.runnable == obj) { // We do comparison exactly how Handler does inside return curr.remove(); } curr = curr.next; } } finally { lock.unlock(); } return null; } }}
10.anim文件中:
①bottom_out.xml:
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromYDelta="0" android:toYDelta="100%p"/> <alpha android:fromAlpha="1.0" android:toAlpha="0.0"/>set>
②left_in.xml:
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromXDelta="-100%p" android:toXDelta="0.0"/> <alpha android:fromAlpha="0.0" android:toAlpha="1.0"/>set>
③left_out.xml:
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromXDelta="0" android:toXDelta="-100%p"/> <alpha android:fromAlpha="1.0" android:toAlpha="0.0"/>set>
④right_in.xml:
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromXDelta="100%p" android:toXDelta="0"/> <alpha android:fromAlpha="0.0" android:toAlpha="1.0"/>set>
⑤right_out.xml:
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromXDelta="0" android:toXDelta="100%p"/> <alpha android:fromAlpha="1.0" android:toAlpha="0.0"/>set>
⑥top_in.xml:
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromYDelta="-100%p" android:toYDelta="0.0"/> <alpha android:fromAlpha="0.0" android:toAlpha="1.0"/>set>
11.demo下载地址:
http://download.csdn.net/detail/afanbaby/9870676
本人菜鸟一个,有什么不对的地方希望大家指出评论,大神勿喷,希望大家一起学习进步!
更多相关文章
- Android实现定时任务及闹钟
- Android恢复出厂设置流程分析
- Android(安卓)Material Design新UI控件使用大全 三
- Android(安卓)壁纸设置_01
- Android开源项目:GifView——Android显示GIF动画
- Android(安卓)Design Support Library 控件的使用
- 【Android开发 蓝牙连接状态】Android实时检测蓝牙连接状态
- Android使用ViewPager、PhotoView实现类似QQ空间图片浏览功能
- 【Android】Ripple使用总结及ClickableSpan的冲突解决