Android高仿京东垂直循环滚动新闻栏

实现思路其实很简单,就是一个自定义的LinearLayout,并且textView能够循环垂直滚动,而且条目可以点击,显示区域最多显示2个条目,并且还有交替的属性垂直移动的动画效果,通过线程来控制滚动的实现。

不多说看效果:

代码实现

我们先来为控件设置自定义属性:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="JDAdverView">
<attr name="gap" format="integer" />
<attr name="animDuration" format="integer"/>
</declare-styleable>
</resources>

自定义控件的获取属性方法都一样:

//获取自定义属性
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.JDAdverView);
mAdverHeight = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, jdAdverHeight, getResources().getDisplayMetrics());
int gap = array.getInteger(R.styleable.JDAdverView_gap, mGap);
int animDuration = array.getInteger(R.styleable.JDAdverView_animDuration, mAnimDuration);
//关闭清空TypedArray,防止内存泄露
array.recycle();

然后呢,我们来看一下条目的布局:

<?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="60dp"
android:background="#ffffff"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:id="@+id/tag"
android:textColor="#ff0000"
android:layout_marginLeft="10dp"
android:text="最新"
android:background="@drawable/corner"
android:textSize="18sp"
android:padding="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/title"
android:layout_marginLeft="10dp"
android:singleLine="true"
android:ellipsize="end"
android:textSize="20sp"
android:text="价格惊呆!电信千兆光纤上市"
android:textColor="#000000"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>

布局很简单,效果呢:

不解释,我们来写适配器了:

package com.example.jdadvernotice;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.example.jdadvernotice.entity.AdverNotice;
import com.example.jdadvernotice.view.JDAdverView;
import java.util.List;
/**
* Created by Administrator on 2016/3/20.
* 京东广告栏数据适配器
*
*/
public class JDViewAdapter {
private List<AdverNotice> mDatas;
public JDViewAdapter(List<AdverNotice> mDatas) {
this.mDatas = mDatas;
if (mDatas == null || mDatas.isEmpty()) {
throw new RuntimeException("nothing to show");
}
}
/**
* 获取数据的条数
* @return
*/
public int getCount() {
return mDatas == null ? 0 : mDatas.size();
}

/**
* 获取摸个数据
* @param position
* @return
*/
public AdverNotice getItem(int position) {
return mDatas.get(position);
}
/**
* 获取条目布局
* @param parent
* @return
*/
public View getView(JDAdverView parent) {
return LayoutInflater.from(parent.getContext()).inflate(R.layout.item, null);
}

/**
* 条目数据适配
* @param view
* @param data
*/
public void setItem(final View view, final AdverNotice data) {
TextView tv = (TextView) view.findViewById(R.id.title);
tv.setText(data.title);
TextView tag = (TextView) view.findViewById(R.id.tag);
tag.setText(data.url);
//你可以增加点击事件
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//比如打开url
Toast.makeText(view.getContext(), data.url, Toast.LENGTH_SHORT).show();
}
});
}
}

然后我们就来自定义view:

package com.example.jdadvernotice.view;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.widget.LinearLayout;
import com.example.jdadvernotice.JDViewAdapter;
import com.example.jdadvernotice.R;
/**
* Created by zengyu on 2016/3/20.
*/
public class JDAdverView extends LinearLayout {
//控件高度
private float mAdverHeight = 0f;
//间隔时间
private final int mGap = 4000;
//动画间隔时间
private final int mAnimDuration = 1000;
//显示文字的尺寸
private final float TEXTSIZE = 20f;
private JDViewAdapter mAdapter;
private final float jdAdverHeight = 50;
//显示的view
private View mFirstView;
private View mSecondView;
//播放的下标
private int mPosition;
//线程的标识
private boolean isStarted;
//画笔
private Paint mPaint;

public JDAdverView(Context context) {
this(context, null);
}

public JDAdverView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}

public JDAdverView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr);
}

/**
* 初始化属性
* @param context
* @param attrs
* @param defStyleAttr
*/
private void init(Context context, AttributeSet attrs, int defStyleAttr) {
//设置为垂直方向
setOrientation(VERTICAL);
//抗锯齿效果
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
//获取自定义属性
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.JDAdverView);
mAdverHeight = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, jdAdverHeight, getResources().getDisplayMetrics());
int gap = array.getInteger(R.styleable.JDAdverView_gap, mGap);
int animDuration = array.getInteger(R.styleable.JDAdverView_animDuration, mAnimDuration);

if (mGap <= mAnimDuration) {
gap = mGap;
animDuration = mAnimDuration;
}
//关闭清空TypedArray
array.recycle();
}

/**
* 设置数据
*/
public void setAdapter(JDViewAdapter adapter) {
this.mAdapter = adapter;
setupAdapter();
}

/**
* 开启线程
*/
public void start() {

if (!isStarted && mAdapter.getCount() > 1) {
isStarted = true;
postDelayed(mRunnable, mGap);//间隔mgap刷新一次UI
}
}

/**
* 暂停滚动
*/
public void stop() {
//移除handle更新
removeCallbacks(mRunnable);
//暂停线程
isStarted = false;
}
/**
* 设置数据适配
*/
private void setupAdapter() {
//移除所有view
removeAllViews();
//只有一条数据,不滚东
if (mAdapter.getCount() == 1) {
mFirstView = mAdapter.getView(this);
mAdapter.setItem(mFirstView, mAdapter.getItem(0));
addView(mFirstView);
} else {
//多个数据
mFirstView = mAdapter.getView(this);
mSecondView = mAdapter.getView(this);
mAdapter.setItem(mFirstView, mAdapter.getItem(0));
mAdapter.setItem(mSecondView, mAdapter.getItem(1));
//把2个添加到此控件里
addView(mFirstView);
addView(mSecondView);
mPosition = 1;
isStarted = false;
}
}
/**
* 测量控件的宽高
*
* @param widthMeasureSpec
* @param heightMeasureSpec
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (LayoutParams.WRAP_CONTENT == getLayoutParams().height) {
getLayoutParams().height = (int) mAdverHeight;
} else {
mAdverHeight = getHeight();
}

if (mFirstView != null) {
mFirstView.getLayoutParams().height = (int) mAdverHeight;
}
if (mSecondView != null) {
mSecondView.getLayoutParams().height = (int) mAdverHeight;
}
}

/**
* 画布局
*
* @param canvas
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(Color.WHITE);
mPaint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, TEXTSIZE, getResources().getDisplayMetrics()));
mPaint.setStyle(Paint.Style.STROKE);
canvas.drawText("瑞士维氏军刀", TEXTSIZE, getHeight() * 2 / 3, mPaint);//写文字2/3的高度
}
/**
* 垂直滚蛋
*/
private void performSwitch() {
//属性动画控制控件滚动,y轴方向移动
ObjectAnimator animator1 = ObjectAnimator.ofFloat(mFirstView, "translationY", mFirstView.getTranslationY() - mAdverHeight);
ObjectAnimator animator2 = ObjectAnimator.ofFloat(mSecondView, "translationY", mSecondView.getTranslationY() - mAdverHeight);
//动画集
AnimatorSet set = new AnimatorSet();
set.playTogether(animator1, animator2);//2个动画一起
set.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {//动画结束
mFirstView.setTranslationY(0);
mSecondView.setTranslationY(0);
View removedView = getChildAt(0);//获得第一个子布局
mPosition++;
//设置显示的布局
mAdapter.setItem(removedView, mAdapter.getItem(mPosition % mAdapter.getCount()));
//移除前一个view
removeView(removedView);
//添加下一个view
addView(removedView, 1);
}
});
set.setDuration(mAnimDuration);//持续时间
set.start();//开启动画
}
private AnimRunnable mRunnable = new AnimRunnable();
private class AnimRunnable implements Runnable {
@Override
public void run() {
performSwitch();
postDelayed(this, mGap);
}
}

/**
* 销毁View的时候调用
*/
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
//停止滚动
stop();
}
/**
* 屏幕 旋转
*
* @param newConfig
*/
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
}

从上面可以看出,控件最多可以显示2个条目,并且用线程控制,根据条目的下标轮流滚动显示。

具体使用代码:

初始化数据:

private void initData() {
datas.add(new AdverNotice("瑞士维氏军刀 新品满200-50","最新"));
datas.add(new AdverNotice("家居家装焕新季,讲199减100!","最火爆"));
datas.add(new AdverNotice("带上相机去春游,尼康低至477","HOT"));
datas.add(new AdverNotice("价格惊呆!电信千兆光纤上市","new"));
}

绑定适配器开启滚动线程:

initData();
final JDViewAdapter adapter = new JDViewAdapter(datas);
final JDAdverView tbView = (JDAdverView) findViewById(R.id.jdadver);
tbView.setAdapter(adapter);
//开启线程滚东
tbView.start();

就写到这里吧,很晚了睡觉,欢迎大家前来拍砖。

以上内容是针对Android高仿京东垂直循环滚动新闻栏的全部介绍,希望对大家以上帮助!

(0)

相关推荐

  • Android中使用TextView实现高仿京东淘宝各种倒计时效果

    今天给大家带来的是仅仅使用一个TextView实现一个高仿京东.淘宝.唯品会等各种电商APP的活动倒计时.最近公司一直加班也没来得及时间去整理,今天难得休息想把这个分享给大家,只求共同学习,以及自己后续的复习.为什么会想到使用一个TextView来实现呢?因为最近公司在做一些优化的工作,其中就有一个倒计时样式,原来开发的这个控件的同事使用了多个TextView拼接在一起的,实现的代码冗余比较大,故此项目经理就说:小宏这个就交给你来优化了,并且还要保证有一定的扩展性,当时就懵逼了.不知道从何处开始

  • Android TabLayout实现京东详情效果

    Google在2015的IO大会上,给我们带来了更加详细的Material Design设计规范,同时,也给我们带来了全新的Android Design Support Library,在这个support库里面,Google给我们提供了更加规范的MD设计风格的控件.最重要的是,Android Design Support Library的兼容性更广,直接可以向下兼容到Android 2.2. 这两天需要做一个仿京东详情的页面,上面的Tab切换,以前都是自己写Viewpager+fragment

  • Android 仿淘宝、京东商品详情页向上拖动查看图文详情控件DEMO详解

    一.淘宝商品详情页效果 我们的效果 二.实现思路 使用两个scrollView,两个scrollView 竖直排列,通过自定义viewGroup来控制两个scrollView的竖直排列,以及滑动事件的处理.如下图 三.具体实现 1.继承viewGroup自定义布局View 重写onMeasure()和onLayout方法,在onLayout方法中完成对两个子ScrollView的竖直排列布局,代码如下: 布局文件: <RelativeLayout xmlns:android="http:/

  • Android仿支付宝、京东的密码键盘和输入框

    首先看下效果图 一:布局代码 键盘由0~9的数字,删除键和完成键组成,也可以根据需求通过GridView适配器的getItemViewType方法来定义.点击键的时候背景有变色的效果. 密码输入框由六个EditText组成,每个输入框最对能输入一个数字,监听最后一个输入框来完成密码输入结束的监听. 二:键盘 键盘中的主要逻辑处理,键盘样式,item的点击事件 @Override public int getViewTypeCount() { return 2; } @Override publi

  • Android仿京东首页轮播文字效果

    京东客户端的轮播文字效果: 本次要实现的只是后面滚动的文字(前面的用ImageView或者TextView实现即可),看一下实现的效果 实现思路 上图只是一个大概的思路,要实现还需要完善更多的细节,下面会一步步的来实现这个效果: 1.封装数据源:从图上可以看到,轮播的文字是分为两个部分的,暂且把它们分别叫做前缀和内容,而且实际的使用过程中点击轮播图肯定是需要跳转页面的,而且大部分应该是WebView,不妨我们就设置点击时候需要获取的内容就是一个链接,那么数据源的结构就很明了了 创建ADEnity

  • 安卓(android)仿电商app商品详情页按钮浮动效果

    1.效果图如下: 这效果用户体验还是很酷炫,今天我们就来讲解如何实现这个效果. 2.分析 为了方便理解,作图分析 如图所示,整个页面分为四个部分: 1.悬浮内容,floatView 2.顶部内容,headView 3.中间内容,与悬浮内容相同,middleView 4.商品详情展示页面,detailView 因为页面内容高度会超出屏幕,所以用Scrollview实现滚动,悬浮view与scrollview同级,都在一个帧布局或者相对布局中. 当y方向的滚动距离小于中间的内容middleView到

  • Android仿京东、天猫商品详情页

    前言 前面在介绍控件TabLayout控件和CoordinatorLayout使用的时候说了下实现京东.天猫详情页面的效果,今天要说的是优化版,是我们线上实现的效果,首先看一张效果: 项目结构分析 首先我们来分析一下要实现上面的效果,我们需要怎么做.顶部是一个可以滑动切换Tab,可以用ViewPager+Fragment实现,也可以使用系统的TabLayout控件实现:而下面的 View是一个可以滑动拖动效果的View,可以采用网上一个叫做DragLayout的控件,我这里是自己实现了一个,主要

  • Android仿淘宝商品拖动查看详情及标题栏渐变功能

    绪论 最近一直比较忙,也没抽出时间来写博客,也不得不说是自己犯了懒癌,人要是一懒就什么事都不想做了,如果不能坚持下来的话,那么估计就废了,��.最近自己攒了好多东西,接下来的时间我会慢慢都分享出来的.好了废话不多说了,下面我们开始正题: 今天要分享的是淘宝的详情页,之前在淘宝上买东西的时候看到淘宝的详情页效果比较不错,所以今天就来仿一下它的效果吧,可能没有淘宝的好,希望见谅啊. 先上效果图: 这是淘宝的: 我自己做的: 怎么样效果还差不多吧?GIF图效果看的不太清楚,见谅. 下面我们来看看怎么实

  • Android仿京东首页画轴效果

    记得之前京东首页有一个效果,有一个画轴,然后可以滚动画轴,去打开画(不知道怎么去形容这个效果,就叫做画轴效果吧- -!),然后去做相关操作,刚开始看到这个效果,想法是动态的去改变一个ImageView的高度,基本效果也就出来了,不过滚动部分的内容,当时接触的也不是很多,只是看过一些大牛的博客,略微了解了一点,当时也忙着写项目,也就没去多想,前些天忽然想到这个效果,就想着实现一下,不过京东新版本好像去掉这个东西了,只能凭着自己的记忆来大概搞一下,也是对滑动这部分内容的一个小练习吧. 先看一下效果图

  • Android高仿京东垂直循环滚动新闻栏

    实现思路其实很简单,就是一个自定义的LinearLayout,并且textView能够循环垂直滚动,而且条目可以点击,显示区域最多显示2个条目,并且还有交替的属性垂直移动的动画效果,通过线程来控制滚动的实现. 不多说看效果: 代码实现 我们先来为控件设置自定义属性: <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="JDAdv

  • Android仿京东快报信息滚动效果

    先来看看效果吧,Android仿京东快报信息滚动效果,具体内容如下 (截图效果不是很好,但是差不多出来了) 代码: package com.test.scrolltransptoolbar; import android.content.Context; import android.graphics.Color; import android.os.Handler; import android.text.TextUtils; import android.util.AttributeSet;

  • Android 高仿斗鱼滑动验证码

    如下图.在Android上实现起来就不太容易,有些效果还是不如web端酷炫.) 我们的Demo,Ac娘镇楼 (图很渣,也忽略底下的SeekBar,这不是重点) 一些动画,效果录不出来了,大家可以去斗鱼web端看一下,然后下载Demo看一下,效果还是可以的. 代码 传送门: https://github.com/mcxtzhang/SwipeCaptcha 我们的Demo和web端基本上一样. 那么本控件包含不仅包含以下功能: 随机区域起点(左上角x,y)生成一个验证码阴影.验证码拼图 凹凸图形会

  • Android高仿微信表情输入与键盘输入详解

    最近公司在项目上要使用到表情与键盘的切换输入,自己实现了一个,还是存在些缺陷,比如说键盘与表情切换时出现跳闪问题,这个相当困扰我,不过所幸在Github(其中一个不错的开源项目,其代码整体结构很不错)并且在论坛上找些解决方案,再加上我也是研究了好多个开源项目的代码,最后才苦逼地整合出比较不错的实现效果,可以说跟微信基本一样(嘿嘿,只能说目前还没发现大Bug,若发现大家一起日后慢慢完善,这里我也只是给出了实现方案,拓展其他表情我并没有实现哈,不过代码中我实现了一个可拓展的fragment模板以便大

  • Android 高仿微信朋友圈拍照上传功能

    模仿微信朋友圈发布动态,输入文字支持文字多少高度自增,有一个最小输入框高度,输入文字有限制,不过这些都很easy! 1. PhotoPicker的使用 这是一个支持选择多张图片,点击图片放大,图片之间左右滑动互相切换的库,同时支持图片删除的库,效果类似微信. (1) 添加PhotoPicker的架包 (2) 使用 选择图片:安卓6.0以后需要在代码中添加读写sd卡和相机的权限 当然清单文件中也需要添加的 PhotoPicker.builder() .setPhotoCount(maxPhoto)

  • WinForm实现仿视频播放器左下角滚动新闻效果的方法

    本文实例讲述了WinForm实现仿视频播放器左下角滚动新闻效果的方法.分享给大家供大家参考.具体实现方法如下: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using Syst

  • Android 高仿微信语音聊天页面高斯模糊(毛玻璃效果)

    目前的应用市场上,使用毛玻璃效果的APP随处可见,比如用过微信语音聊天的人可以发现,语音聊天页面就使用了高斯模糊效果. 先看下效果图: 仔细观察上图,我们可以发现,背景图以用户头像为模板,对其进行了高斯模糊,并把它作为整个页面的背景色. 关于Android如何快速实现高斯模糊(毛玻璃效果),网上一堆相关介绍,可参考下面文章一种快速毛玻璃虚化效果实现–Android. 下面直接给出模糊化工具类(已验证可行): import android.graphics.Bitmap; /** * 快速模糊化工

  • Android高仿微信聊天界面代码分享

    微信聊天现在非常火,是因其界面漂亮吗,哈哈,也许吧.微信每条消息都带有一个气泡,非常迷人,看起来感觉实现起来非常难,其实并不难.下面小编给大家分享实现代码. 先给大家展示下实现效果图: OK,下面我们来看一下整个小项目的主体结构: 下面是Activity的代码: package com.way.demo; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import jav

  • Android 高仿QQ 沉浸式状态栏

    前言: 在进入今天正题前,还是老样子先谈谈感想吧,最近感觉整个都失去了方向感,好迷茫!找工作又失败了,难道Android真的饱和了?这两天我一直没出门,除了下楼哪外卖就是宅宿舍了,静想了许久,我还是不能忘了初心,我相信我找不到工作的原因有很多,最关键的还是要技术够硬才行啊,奔跑吧孩子!接下来我就给大家介绍怎样快速打造沉浸式状态栏吧,虽然感觉有点相见恨晚,但其实不完! 一:何为沉浸式状态栏? 沉浸式状态栏是Google从Android 4.4开始,给我们开发者提供的一套能透明的系统ui样式,这样样

随机推荐