前言:例如某些淘宝商店里实现的上下公告栏,对其进行点击时会跳转到相应的界面
去。
实现思路:我们可以分成两部分进行实现一个是
viewFlipper
的为其动态添加相应布局。第二个是动态实现添加TextView并对其进行销毁与添加点击事件。
首先我们完成第一个(实现viewFlipper):
<?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:paddingTop="8dp" android:paddingBottom="8dp" android:orientation="horizontal"> <ViewFlipper android:id="@+id/viewFlipper" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:flipInterval="5000" android:padding="8dp" > </ViewFlipper> </LinearLayout>
本质上就是对
MarqueeTextView
这个自定义控件布局的添加。
主要自定义控件,接口代码的实现(全部)
package com.example.com.mlsdome.Activity.Cuscontrols; import android.content.Context; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.animation.AnimationUtils; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.ViewFlipper; import com.example.com.mlsdome.R; /** * Created by 12697 on 2017/3/27. */ public class MarqueeTextView extends LinearLayout { /* * 实现点击事件的两个参数 * */ private String[] textArrays; private MarqueeTextViewClickLisnter marqueeTextViewClickLisnter; private Context mcontext; private View marqueeTextView; /* * 上下滑动的效果 * * */ private ViewFlipper viewFlipper; public MarqueeTextView(Context context) { super(context); this.mcontext=context; initBasicView(); } public MarqueeTextView(Context context, AttributeSet attrs) { super(context, attrs); this.mcontext=context; initBasicView(); } /* * * 实现点击事件 * * */ public void setTextArraysAndClickListener(String[] textArrays,MarqueeTextViewClickLisnter marqueeTextViewClickLisnter) { this.textArrays=textArrays; this.marqueeTextViewClickLisnter=marqueeTextViewClickLisnter; initMarqueeTextView(textArrays,marqueeTextViewClickLisnter); } /* * 如果textArrays长度为0是便返回 * * */ public void initMarqueeTextView(String[] textArrays,MarqueeTextViewClickLisnter marqueeTextViewClickLisnter) { if (textArrays.length==0) { return; } int i=0; viewFlipper.removeAllViews(); /* * 给viewflipper添加textview与layoutparams样式 * * */ while (i<textArrays.length) { TextView textView=new TextView(mcontext); textView.setText(textArrays[i]); textView.setOnClickListener(marqueeTextViewClickLisnter); LayoutParams layoutParams=new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT); viewFlipper.addView(textView,layoutParams); i++; } } /* * 添加布局与为viewfilpper添加上下,左右动画 * * */ public void initBasicView() { marqueeTextView = LayoutInflater.from(mcontext).inflate(R.layout.marquee_textview_layout, null); LayoutParams layoutParams = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); addView(marqueeTextView, layoutParams); viewFlipper = (ViewFlipper) marqueeTextView.findViewById(R.id.viewFlipper); viewFlipper.setInAnimation(AnimationUtils.loadAnimation(mcontext, R.anim.slide_in_bottom)); viewFlipper.setOutAnimation(AnimationUtils.loadAnimation(mcontext, R.anim.slide_out_top)); viewFlipper.startFlipping(); } /* * 释放资源 * * */ public void releaseResources() { if (marqueeTextView != null) { if (viewFlipper != null) { viewFlipper.stopFlipping(); viewFlipper.removeAllViews(); viewFlipper = null; } marqueeTextView = null; } } }
package com.example.com.mlsdome.Activity.Cuscontrols; import android.view.View; /** * Created by 廖成康 on 2017/3/27. */ /* * * 实现接口 * * */ public interface MarqueeTextViewClickLisnter extends View.OnClickListener { void OnClick(View view); }
接下来进行代码的分析:
从小到大:
首先是点击的接口的实现:自己定义一个接口并在里面
定义这个方法;
然后是这个自定义控件的构造的实现:
public MarqueeTextView(Context context) { super(context); this.mcontext=context; initBasicView(); } public MarqueeTextView(Context context, AttributeSet attrs) { super(context, attrs); this.mcontext=context; initBasicView(); }
在这两个构造函数里面:
主要是实现的是
public void initBasicView() { marqueeTextView = LayoutInflater.from(mcontext).inflate(R.layout.marquee_textview_layout, null); LayoutParams layoutParams = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); addView(marqueeTextView, layoutParams); viewFlipper = (ViewFlipper) marqueeTextView.findViewById(R.id.viewFlipper); viewFlipper.setInAnimation(AnimationUtils.loadAnimation(mcontext, R.anim.slide_in_bottom)); viewFlipper.setOutAnimation(AnimationUtils.loadAnimation(mcontext, R.anim.slide_out_top)); viewFlipper.startFlipping(); }
对于布局的添加,并对
viewFlipper
添加动画且对其进行开启开启动画之后动态的去添加和溢出TextView
public void initMarqueeTextView(String[] textArrays,MarqueeTextViewClickLisnter marqueeTextViewClickLisnter) { if (textArrays.length==0) { return; } int i=0; viewFlipper.removeAllViews(); /* * 给viewflipper添加textview与layoutparams样式 * * */ while (i<textArrays.length) { TextView textView=new TextView(mcontext); textView.setText(textArrays[i]); textView.setOnClickListener(marqueeTextViewClickLisnter); LayoutParams layoutParams=new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT); viewFlipper.addView(textView,layoutParams); i++; } }
实现点击事件,对外部提供方法
/* * * 实现点击事件 * * */ public void setTextArraysAndClickListener(String[] textArrays,MarqueeTextViewClickLisnter marqueeTextViewClickLisnter) { this.textArrays=textArrays; this.marqueeTextViewClickLisnter=marqueeTextViewClickLisnter; initMarqueeTextView(textArrays,marqueeTextViewClickLisnter); }
最后,也十分的重要,因为在textView不断地创建和销毁的过程中,
我们必须要做好控制,如何对资源进行很好的回收和释放:
/* * 释放资源 * * */ public void releaseResources() { if (marqueeTextView != null) { if (viewFlipper != null) { viewFlipper.stopFlipping(); viewFlipper.removeAllViews(); viewFlipper = null; } marqueeTextView = null; } }
到这一步,基本上我们就完成了这个功能了,当然还是需要一些动画资源的
<?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>
<?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>
ok,接下来就是在主程序里面就可以调用了;
package com.example.com.mlsdome.Activity; import android.os.Bundle; import android.support.annotation.Nullable; import android.view.View; import com.example.com.mlsdome.Activity.Cuscontrols.MarqueeTextView; import com.example.com.mlsdome.Activity.Cuscontrols.MarqueeTextViewClickLisnter; import com.example.com.mlsdome.R; /** * Created by 12697 on 2017/3/27. */ public class SignActivity extends ContextViewActivity { private String[] textArrays = new String[]{"this is content No.1","this is content No.2","this is content No.3"}; private MarqueeTextView marqueeTextView; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setView(); showTitle("报名"); init(); marqueeTextView.setTextArraysAndClickListener(textArrays, new MarqueeTextViewClickLisnter() { @Override public void OnClick(View view) { } @Override public void onClick(View view) { } }); } private void init() { marqueeTextView= (MarqueeTextView) findViewById(R.id.marqueeTv); } @Override public int setView() { return R.layout.sign_layout; } @Override protected void onDestroy() { marqueeTextView.releaseResources(); super.onDestroy(); } }
因为这里面的程序比较简单我就不多做解释了!
OK,到这里我们的功能也已经实现了