今天看了淘宝头条的的滚动,感觉用户体验非常好,然后在就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

本人菜鸟一个,有什么不对的地方希望大家指出评论,大神勿喷,希望大家一起学习进步!

更多相关文章

  1. Android实现定时任务及闹钟
  2. Android恢复出厂设置流程分析
  3. Android(安卓)Material Design新UI控件使用大全 三
  4. Android(安卓)壁纸设置_01
  5. Android开源项目:GifView——Android显示GIF动画
  6. Android(安卓)Design Support Library 控件的使用
  7. 【Android开发 蓝牙连接状态】Android实时检测蓝牙连接状态
  8. Android使用ViewPager、PhotoView实现类似QQ空间图片浏览功能
  9. 【Android】Ripple使用总结及ClickableSpan的冲突解决

随机推荐

  1. android studio 生成 jniLibs 目录
  2. android图片预览
  3. 安卓四大组件之activity
  4. android 简单线程同步之CountDownLatch
  5. android activity切换翻转效果
  6. [Android]帧率测试
  7. Android(安卓)自定义手写签名并保存到sdc
  8. Android API对应版本关系(最新更新2019年1
  9. Android:ImageView图片缩放、居中
  10. [Android 编译] Ubuntu 16.04 LTS 成功编