本项目是用eclipse软件编写,经过我的亲自实践,其真实有效,希望能给您有所帮助 项目版本:android5.1.1 AVD建议:android4.4.2及以上 若有不足之处或不对的地方,欢迎大佬们指点 |
水平滑动广告栏主要用于展示广告信息或者活动信息
将广告栏界面所需图片 default_img.png
, banner_1.png
、banner_2.png
、banner_3.png
导入到drawable
文件夹中
main_adbanner.xml
res/layout
文件夹中新建main_adbanner.xml
文件,采用的是相对布局RelativeLayout
。代码如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rl_adBanner"
android:layout_width="match_parent"
android:layout_height="160dp"
android:background="#eeeeee"
android:orientation="vertical" >
<android.support.v4.view.ViewPager
android:id="@+id/vp_advertBanner"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginBottom="1dp"
android:background="@drawable/default_img"
android:gravity="center" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@android:color/transparent">
<china.ynyx.heyunhui.view.ViewPagerIndicator
android:id="@+id/vpi_advert_indicator"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="center"
android:padding="4dp" />
LinearLayout>
RelativeLayout>
导入android.support.v4包方法:
水平滑动广告栏底部的小圆点控件就需要通过自定义控件完成
(1)indicator_on.xml
和 indicator_off.xml
的创建
在drawable
文件夹下分别创建了 indicator_on.xml
和indicator_off.xml
两个文件
具体代码如下:indicator_on.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<size android:height="6dp" android:width="6dp"/>
<solid android:color="#00ABF8"/>
shape>
indicator_off.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<size android:height="6dp" android:width="6dp"/>
<solid android:color="#737373"/>
shape>
shape用于设定形状,可以用在选择器和布局中,shape默认为矩形 (rectangle),可设置为椭圆形(oval)、线性形状(line)、环形(ring)。size表示大小, 可设置宽高。solid表示内部填充色。
(2)在china.ynyx.heyunhui.view
包中创建一个ViewPagerIndicator
类并继承 LinearLayout
类
具体代码如下:ViewPagerIndicator.java
package china.ynyx.heyunhui.view;
import android.content.Context;
import android.util.AttributeSet;
import android.view.Gravity;
import android.widget.ImageView;
import android.widget.LinearLayout;
import china.ynyx.heyunhui.R;
public class ViewPagerIndicator extends LinearLayout {
private int mCount;//小圆点的个数
private int mIndex;//当前小圆点的位置
private Context context;
public ViewPagerIndicator(Context context) {
this(context, null);
}
public ViewPagerIndicator(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
setGravity(Gravity.CENTER);//设置此布局居中
}
/**
*设置滑动到当前小圆点时其他圆点的位置
*/
public void setCurrentPosition(int currentIndex) {
mIndex = currentIndex;//当前小圆点
removeAllViews();//移除界面上存在的view
int pex = 5;
for (int i = 0; i < mCount; i++) {
//创建一个ImageView控件来放置小圆点
ImageView imageView = new ImageView(context);
if (mIndex == i) {//滑动到的当前界面
//设置小圆点的图片为蓝色图片
imageView.setImageResource(R.drawable.indicator_on);
}else {
//设置小圆点的图片为灰色图片
imageView.setImageResource(R.drawable.indicator_off);
}
imageView.setPadding(pex, 0, pex, 0);//设置小圆点图片的上下左右的padding
addView(imageView);//把此小圆点添加到自定义的ViewPagerIndicator控件上
}
}
/**
* 设置小圆点的数目
*/
public void setCount(int count) {
this.mCount = count;
}
}
在china.ynyx.heyunhui.bean
包中创建一个CourseBean
类。在该类中创建课程所有属性
具体代码如下:CourseBean.java
package china.ynyx.heyunhui.bean;
public class CourseBean {
public int id; //每章节id
public String icon; //广告栏上的图片
}
由于广告栏用到了 ViewPager
控件,因此创建一个AdBannerFragment
类 来设置ViewPager
控件中的数据
选中china.ynyx.heyunhui
包,在该包下创建china.ynyx.heyunhui.fragment
包。在.fragment
包中创建一个 AdBannerFragment
类并继承 Fragment
类
具体代码如下:AdBannerFragment.java
package china.ynyx.heyunhui.fragment;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import china.ynyx.heyunhui.R;
public class AdBannerFragment extends Fragment {
private String ab;// 广告
private ImageView iv;// 图片
public static AdBannerFragment newInstance(Bundle args) {
AdBannerFragment af = new AdBannerFragment();
af.setArguments(args);
return af;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle arg = getArguments();
// 获取广告图片名称
ab = arg.getString("ad");
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
@Override
public void onResume() {
super.onResume();
if (ab != null) {
if ("banner_1".equals(ab)) {
iv.setImageResource(R.drawable.banner_1);
} else if ("banner_2".equals(ab)) {
iv.setImageResource(R.drawable.banner_2);
} else if ("banner_3".equals(ab)) {
iv.setImageResource(R.drawable.banner_3);
}
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (iv != null) {
iv.setImageDrawable(null);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// 创建广告图片控件
iv = new ImageView(getActivity());
ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.FILL_PARENT);
iv.setLayoutParams(lp);// 设置图片宽高参数
iv.setScaleType(ImageView.ScaleType.FIT_XY);// 把图片塞满整个控件
return iv;
}
}
由于广告栏用到了 ViewPager
控件,因此需要创建一个数据适配器AdBannerAdapter
对ViewPager
控件进行数据适配
在 china.ynyx.heyunhui.adapter
包中创建一个 AdBannerAdapter
类继承 FragmentStatePagerAdapter
类并实现 OnTouchListener
接口。
具体代码如下:AdBannerAdapter.java
package china.ynyx.heyunhui.adapter;
import java.util.ArrayList;
import java.util.List;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import china.ynyx.heyunhui.bean.CourseBean;
import china.ynyx.heyunhui.fragment.AdBannerFragment;
import china.ynyx.heyunhui.view.CourseView;
public class AdBannerAdapter extends FragmentStatePagerAdapter implements
OnTouchListener{
private Handler mHandler;
private List<CourseBean> cadl;
public AdBannerAdapter(FragmentManager fm) {
super(fm);
cadl = new ArrayList<CourseBean>();
}
public AdBannerAdapter(FragmentManager fm, Handler handler) {
super(fm);
mHandler = handler;
cadl = new ArrayList<CourseBean>();
}
/**
* 设置数据更新界面
*/
public void setDatas(List<CourseBean> cadl) {
this.cadl = cadl;
notifyDataSetChanged();
}
@Override
public Fragment getItem(int index) {
Bundle args = new Bundle();
if (cadl.size() > 0)
args.putString("ad", cadl.get(index % cadl.size()).icon);
return AdBannerFragment.newInstance(args);
}
@Override
public int getCount() {
return Integer.MAX_VALUE;
}
/**
* 返回数据集的真实容量大小
*/
public int getSize() {
return cadl == null ? 0 : cadl.size();
}
@Override
public int getItemPosition(Object object) {
// 防止刷新结果显示列表的时候出现缓存数据,重载这个函数 使之默认返回POSITION_NONE
return POSITION_NONE;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
mHandler.removeMessages(CourseView.MSG_AD_SLID);
return false;
}
}
main_view_course.xml
用于显示广告栏界面res/layout
文件夹中新建main_view_course.xml
文件,代码如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:orientation="vertical" >
<include layout="@layout/main_adbanner" />
LinearLayout>
由于广告栏每隔一段时间会自动切换到下一张图片,因此可以创建一个线程进行实现
在china.ynyx.heyunhui.view
包中创建一个CourseView
类。在该类中,创建界面控件的初始化方法initView()
,在该方法中获取页面布局中需要用到的UI控件并初始化
具体代码如下:CourseView.java
package china.ynyx.heyunhui.view;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import china.ynyx.heyunhui.R;
import china.ynyx.heyunhui.adapter.AdBannerAdapter;
import china.ynyx.heyunhui.bean.CourseBean;
public class CourseView {
private FragmentActivity mContext;
private LayoutInflater mInflater;
private View mCurrentView;
private ViewPager adPager;// 广告
private View adBannerLay;// 广告条容器
private AdBannerAdapter ada;// 适配器
public static final int MSG_AD_SLID = 002;// 广告自动滑动
private ViewPagerIndicator vpi;// 小圆点
private MHandler mHandler;// 事件捕获
private List<CourseBean> cadl;
public CourseView(FragmentActivity context) {
mContext = context;
// 为之后将Layout转化为view时用
mInflater = LayoutInflater.from(mContext);
}
private void createView() {
mHandler = new MHandler();
initAdData();
initView();
new AdAutoSlidThread().start();
}
/**
* 事件捕获
*/
class MHandler extends Handler {
@Override
public void dispatchMessage(Message msg) {
super.dispatchMessage(msg);
switch (msg.what) {
case MSG_AD_SLID:
if (ada.getCount() > 0) {
adPager.setCurrentItem(adPager.getCurrentItem() + 1);
}
break;
}
}
}
/**
* 广告栏自动滑动
* 创 建 一 个 线 程 , 并 让 该 线 程 休 眠 5000毫秒
*/
class AdAutoSlidThread extends Thread {
@Override
public void run() {
super.run();
while (true) {
try {
sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (mHandler != null)
mHandler.sendEmptyMessage(MSG_AD_SLID);
}
}
}
/**
* 初始化控件
*/
private void initView() {
mCurrentView = mInflater.inflate(R.layout.main_view_course, null);
adPager = (ViewPager) mCurrentView.findViewById(R.id.vp_advertBanner);
adPager.setLongClickable(false);
ada = new AdBannerAdapter(mContext.getSupportFragmentManager(),
mHandler);
adPager.setAdapter(ada);// 给ViewPager设置适配器
adPager.setOnTouchListener(ada);
vpi = (ViewPagerIndicator) mCurrentView
.findViewById(R.id.vpi_advert_indicator);// 获取广告条上的小圆点
vpi.setCount(ada.getSize());// 设置小圆点的个数
adBannerLay = mCurrentView.findViewById(R.id.rl_adBanner);
adPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
if (ada.getSize() > 0) {
//由于index数据在滑动时是累加的,因此用index % ada.getSize()来标记滑动到的当前位置
vpi.setCurrentPosition(position % ada.getSize());
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
resetSize();
if (cadl != null) {
if (cadl.size() > 0) {
vpi.setCount(cadl.size());
vpi.setCurrentPosition(0);
}
ada.setDatas(cadl);
}
}
/**
* 计算广告栏控件大小
* 首先获取屏幕的宽度,之后将广 告栏控件宽度设为屏幕的宽,将广告栏的髙度设为屏幕宽度的一半
*/
private void resetSize() {
int sw = getScreenWidth(mContext);
int adLheight = sw / 2;// 广告条高度
ViewGroup.LayoutParams adlp = adBannerLay.getLayoutParams();
adlp.width = sw;
adlp.height = adLheight;
adBannerLay.setLayoutParams(adlp);
}
/**
* 读取屏幕宽
*/
public static int getScreenWidth(Activity context) {
DisplayMetrics metrics = new DisplayMetrics();
Display display = context.getWindowManager().getDefaultDisplay();
display.getMetrics(metrics);
return metrics.widthPixels;
}
/**
* 初始化广告中的数据
*/
private void initAdData() {
cadl = new ArrayList<CourseBean>();
for (int i = 0; i < 3; i++) {
CourseBean bean = new CourseBean();
bean.id=(i + 1);
switch (i) {
case 0:
bean.icon="banner_1";
break;
case 1:
bean.icon="banner_2";
break;
case 2:
bean.icon="banner_3";
break;
default:
break;
}
cadl.add(bean);
}
}
/**
* 获取当前在导航栏上方显示对应的View
*/
public View getView() {
if (mCurrentView == null) {
createView();
}
return mCurrentView;
}
/**
* 显示当前导航栏上方所对应的view界面
*/
public void showView() {
if (mCurrentView == null) {
createView();
}
mCurrentView.setVisibility(View.VISIBLE);
}
}
(1)由于课程界面是通过底部导航栏跳转的,因此需要在 MainActivity.java
文件的 private ExercisesView mExercisesView;
语句上方添加如下代码并导入相应的包:
private CourseView mCourseView;
(2)在createView()
方法中,当case
为0时,在注释//课程界面
的下方添加如下代码:
if (mCourseView == null) {
mCourseView = new CourseView(this);
mBodyLayout.addView(mCourseView.getView());
} else {
mCourseView.getView();
}
mCourseView.showView();
参考资料:《android项目实战——博学谷》(黑马程序员著)