上一次自己做了两套布局的平移动画来实现类似淘宝头条的滚动效果,后来又在github上找到了孙福大神写的自定义控件 地址:https://github.com/sfsheng0322/MarqueeView,发现非常不错,就尝试研究了下。
其中进出的动画我没动,大家可以自己定制,我先把孙福大神的粘贴出来:
出去的anim_marquee_out:
以上是自定义的MarqueeView,关于资料查找的方面也看到过有些大神在view上加了监听,但只能实现一个textview的来回的上下的滚动,而想实现两个textview的来回的滚动,这个点击事件就不准确了,下面看是如何实现精确的点击的。
狗尾续貂之作,望大家不要见笑!!
但是美中不足的是:每个滚动的textview的点击事件是无法获取到的,因此自己又在孙福大神的代码基础上加上了每个textview的点击事件,算是狗尾续貂吧!
好了,废话不多说,先看效果图:
模拟器的效果可能有点卡顿,本来想用真机录制的,但是想了想就是一个点击事件的效果,哪怕卡一点也是无伤大雅的。
下面上代码:
第一个是孙福大神的自定义控件MarqueeView,在他的基础上加了view的点击监听。
public class UPMarqueeView extends ViewFlipper {
private Context mContext;
private boolean isSetAnimDuration = false;
private int interval = 3000;
/**
* 动画时间
*/
private int animDuration = 500;
public UPMarqueeView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0);
}
private void init(Context context, AttributeSet attrs, int defStyleAttr) {
this.mContext = context;
setFlipInterval(interval);
Animation animIn = AnimationUtils.loadAnimation(mContext, R.anim.anim_marquee_in);
if (isSetAnimDuration)
animIn.setDuration(animDuration);
setInAnimation(animIn);
Animation animOut = AnimationUtils.loadAnimation(mContext, R.anim.anim_marquee_out);
if (isSetAnimDuration)
animOut.setDuration(animDuration);
setOutAnimation(animOut);
}
/**
* 设置循环滚动的View数组
*
* @param views
*/
public void setViews(final List<View> views) {
if (views == null || views.size() == 0)
return;
removeAllViews();
for (int i = 0; i < views.size(); i++) {
final int position = i;
// 设置监听回调
views.get(i).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (onItemClickListener != null) {
onItemClickListener.onItemClick(position, views.get(position));
}
}
});
addView(views.get(i));
}
if (views.size() == 1) {
// 可以设置不滚动
} else {
startFlipping();
}
}
/**
* 点击
*/
private OnItemClickListener onItemClickListener;
/**
* 设置监听接口
*
* @param onItemClickListener
*/
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
/**
* item_view的接口
*/
public interface OnItemClickListener {
void onItemClick(int position, View view);
}
}
其中进出的动画我没动,大家可以自己定制,我先把孙福大神的粘贴出来:
进入的 anim_marquee_in:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="300"
android:fromYDelta="100%p"
android:toYDelta="0"/>
<alpha
android:duration="500"
android:fromAlpha="0.0"
android:toAlpha="1.0"/>
</set>
出去的anim_marquee_out:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="400"
android:fromYDelta="0"
android:toYDelta="-100%p"/>
<alpha
android:duration="500"
android:fromAlpha="1.0"
android:toAlpha="0.0"/>
</set>
以上是自定义的MarqueeView,关于资料查找的方面也看到过有些大神在view上加了监听,但只能实现一个textview的来回的上下的滚动,而想实现两个textview的来回的滚动,这个点击事件就不准确了,下面看是如何实现精确的点击的。
MainActivity的相关代码:
public class MainActivity extends Activity {
private UPMarqueeView upview1;
List<String> data = new ArrayList<String>();
List<View> views = new ArrayList<View>();
private TextView tv1;
private TextView tv2;
private RelativeLayout rl;
private RelativeLayout rl2;
private boolean relaOneTouch =false; // 判断两个textview哪个被触摸了
private boolean relaTwoTouch =false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initParam();
initdata();
initView();
}
/**
* 实例化控件
*/
private void initParam() {
upview1 = (UPMarqueeView) findViewById(R.id.upview1);
}
/**
* 初始化界面程序
*/
private void initView() {
setView();
upview1.setViews(views);
upview1.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(int position, View view) {
int num = (position +1) * 2;
if (relaOneTouch) {
Toast.makeText(MainActivity.this, data.get(num-2), 0).show();
relaOneTouch = false;
}else if (relaTwoTouch) {
Toast.makeText(MainActivity.this, data.get(num-1), 0).show();
relaTwoTouch = false;
}else {
}
Log.i("nima", "点击的位置是:" + position);
}
});
}
/**
* 初始化需要循环的View 为了灵活的使用滚动的View,所以把滚动的内容让用户自定义
* 假如滚动的是三条或者一条,或者是其他,只需要把对应的布局,和这个方法稍微改改就可以了,
*/
private void setView() {
for (int i = 0; i < data.size(); i = i + 2) {
// 设置滚动的单个布局
LinearLayout moreView = (LinearLayout) LayoutInflater.from(this).inflate(R.layout.item_view, null);
rl = (RelativeLayout) moreView.findViewById(R.id.rl);
rl2 = (RelativeLayout) moreView.findViewById(R.id.rl2);
tv1 = (TextView) moreView.findViewById(R.id.tv1);
tv2 = (TextView) moreView.findViewById(R.id.tv2);
// 进行对控件赋值
tv1.setText(data.get(i).toString());
if (data.size() == 1) {
// 进行对控件赋值
moreView.findViewById(R.id.rl2).setVisibility(View.GONE);
} else {
if (data.size() > i + 1) {
// 因为淘宝那儿是两条数据,但是当数据是奇数时就不需要赋值第二个,所以加了一个判断,还应该把第二个布局给隐藏掉
tv2.setText(data.get(i + 1).toString());
} else {
moreView.findViewById(R.id.rl2).setVisibility(View.GONE);
}
}
// 最后一次添加的布局的touch事件
rl.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.i("nima", "rl11111倍点击了哈");
relaOneTouch = true;
relaTwoTouch = false;
break;
default:
break;
}
return false;
}
});
rl2.setOnTouchListener(new OnTouchListener() {
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.i("nima", "rl22222222222倍点击了哈");
relaOneTouch = false;
relaTwoTouch = true;
break;
default:
break;
}
return false;
}
});
// 添加到循环滚动数组里面去
views.add(moreView);
}
}
/**
* 初始化数据
*/
private void initdata() {
data = new ArrayList<String>();
data.add("万事如意 哈哈哈哈哈");
data.add("一帆风顺 嘻嘻嘻嘻嘻");
data.add("步步高升 乐乐乐乐乐");
data.add("青春不老 笑笑笑笑笑");
data.add("飞龙在天 强强强强强");
data.add("六六大顺66666666666666666666");
}
}
大致的思路: 1 UPMarqueeView的设置的监听能判断哪个位置滚动的数据被点击了,可以根据位置取得两条数据。
2 根据touch事件的监听来判断上班部分还是下半部分被点击,从而确定精确的数据。
3 事件的分发机制,touch事件和click事件的关系先后,大家自行脑补。
这三点清楚了,基本上就实现了效果图看到的精确的点击。
最后也给出主布局的代码:
activity_main:
<?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="match_parent"
android:orientation="horizontal">
<RelativeLayout
android:layout_width="match_parent"
android:background="#f2f2f2"
android:layout_height="60dp">
<TextView
android:id="@+id/tbtv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_centerVertical="true"
android:textSize="22sp"
android:textColor="#0088ff"
android:text="商圈头条" />
<com.example.scrolltextview.UPMarqueeView
android:id="@+id/upview1"
android:layout_marginLeft="20dp"
android:layout_width="match_parent"
android:layout_toRightOf="@+id/tbtv"
android:layout_centerVertical="true"
android:layout_marginTop="10dp"
android:layout_height="match_parent"></com.example.scrolltextview.UPMarqueeView>
</RelativeLayout>
</LinearLayout>
狗尾续貂之作,望大家不要见笑!!