Imitation of Jingdong Express

Our commonly used Jingdong has a very beautiful effect:
the Jingdong Express on the home page has an infinite carousel bulletin board, let’s look at the effect first:
write picture description here

The content of the announcement slides up from the middle about every 3s, while the next content slides in from the bottom. The whole process is accompanied by the gradual disappearance of the content, and the animation effect is very smooth.

It is simpler to use ViewFlipper.
Take a look at the official comments of the ViewFlipper class:

Simple {@link ViewAnimator} that will animate between two or more views that have been added to it. Only one child is shown at a time. If requested, can automatically flip between each child at a regular interval.
  • 1

Literal translation: ViewFlipper is a container that can switch two or more child View animations added in it, and only one child is displayed at a time point. And it can automatically switch to a child every other time period.
To achieve the switching effect of Jingdong Express, we only need to set the content of the announcement according to the carousel to TextView and add it to ViewFlipper, and set the switching animation between them at the same time.

In order to facilitate direct reuse in the project, we can customize it as a control NoticeView inherited from ViewFlipper.

public class NoticeView extends ViewFlipper implements View.OnClickListener {
    private Context mContext;
    private List<String> mNotices;
    private OnNoticeClickListener mOnNoticeClickListener;

    public NoticeView(Context context) {
        super(context);
    }

    public NoticeView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    private void init(Context context) {
        mContext = context;
        // 轮播间隔时间为3s
        setFlipInterval(3000);
        // 内边距5dp
        setPadding(dp2px(5f), dp2px(5f), dp2px(5f), dp2px(5f));
        // 设置enter和leave动画
        setInAnimation(AnimationUtils.loadAnimation(mContext, R.anim.notice_in));
        setOutAnimation(AnimationUtils.loadAnimation(mContext, R.anim.notice_out));
    }

    /**
     * 添加需要轮播展示的公告
     *
     * @param notices
     */
    public void addNotice(List<String> notices) {
        mNotices = notices;
        removeAllViews();
        for (int i = 0; i < mNotices.size(); i++) {
            // 根据公告内容构建一个TextView
            String notice = notices.get(i);
            TextView textView = new TextView(mContext);
            textView.setSingleLine();
            textView.setText(notice);
            textView.setTextSize(20f);
            textView.setEllipsize(TextUtils.TruncateAt.END);
            textView.setTextColor(Color.parseColor("#666666"));
            textView.setGravity(Gravity.CENTER_VERTICAL|Gravity.CENTER_HORIZONTAL);
            // 将公告的位置设置为textView的tag方便点击是回调给用户
            textView.setTag(i);
            textView.setOnClickListener(this);
            // 添加到ViewFlipper
            NoticeView.this.addView(textView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
        }
    }


    @Override
    public void onClick(View v) {
        int position = (int) v.getTag();
        String notice = (String) mNotices.get(position);
        if (mOnNoticeClickListener != null) {
            mOnNoticeClickListener.onNotieClick(position, notice);
        }
    }

    /**
     * 通知点击监听接口
     */
    public interface OnNoticeClickListener {
        void onNotieClick(int position, String notice);
    }

    /**
     * 设置通知点击监听器
     *
     * @param onNoticeClickListener 通知点击监听器
     */
    public void setOnNoticeClickListener(OnNoticeClickListener onNoticeClickListener) {
        mOnNoticeClickListener = onNoticeClickListener;
    }

    private int dp2px(float dpValue) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                dpValue,
                mContext.getResources().getDisplayMetrics());
    }
}

layout file

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="20sp"
    android:layout_marginLeft="15sp"
    android:layout_marginRight="15sp"
    android:layout_marginTop="20sp"
    android:background="@drawable/jingdong_news_bgcolor"
    android:orientation="horizontal"
    android:paddingLeft="15sp"
    android:paddingRight="15sp">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/jd_news_tit" />

    <com.project.jingdong.customview.NoticeView
        android:id="@+id/notice_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="center_horizontal|center_vertical"
        android:layout_weight="1"></com.project.jingdong.customview.NoticeView>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal|center_vertical"
        android:text="  | 更多 "
        android:textSize="22sp" />
</LinearLayout>

layout style

<?xml version="1.0" encoding="utf-8"?><!-- 定义圆角矩形 -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:padding="10dp"
    android:shape="rectangle">
    <!-- 填充颜色 -->
    <solid android:color="#FFFFFF" />
    <!-- 圆角 -->
    <corners
        android:bottomLeftRadius="16dp"
        android:bottomRightRadius="16dp"
        android:topLeftRadius="16dp"
        android:topRightRadius="16dp" />
    <!-- 边框颜色 -->
    <stroke
        android:width="1dip"
        android:color="#FFFFFF" />
</shape>

The content of the announcement enters the animation notice_in.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <!--平移-->
    <translate
        android:duration="@android:integer/config_mediumAnimTime"
        android:fromYDelta="50%p"
        android:toYDelta="0"/>
    <!--渐变-->
    <alpha
        android:duration="@android:integer/config_mediumAnimTime"
        android:fromAlpha="0.0"
        android:toAlpha="1.0"/>
</set>

Announcement content slide out animation notice_out.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <!--平移-->
    <translate
        android:duration="@android:integer/config_mediumAnimTime"
        android:fromYDelta="0"
        android:toYDelta="-50%p"/>
    <!--渐变-->
    <alpha
        android:duration="@android:integer/config_mediumAnimTime"
        android:fromAlpha="1.0"
        android:toAlpha="0.0"/>
</set>

It can be used directly in Activity or Fragment

  //定义成为一个方法,直接调用就行了
  private void init() {
        NoticeView noticeView = (NoticeView) getActivity().findViewById(R.id.notice_view);
        List<String> notices = new ArrayList<>();
        notices.add("大促销下单拆福袋,亿万新年红包随便拿");
        notices.add("家电五折团,抢十亿无门槛现金红包");
        notices.add("星球大战剃须刀首发送200元代金券");
        noticeView.addNotice(notices);
        noticeView.startFlipping();
    }

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325405765&siteId=291194637