最近整理了一下在自己负责的项目中用到的一些自定义View 实现一些比较热门的功能,写到这里给自己留一份笔记,同时给那些有需要的朋友!
Demo主要是重写了一下Linearlayout,对其填充你想要填充的布局,由于在代码中都添加了注释,这里不再做一一解释了
先看看效果图:
自定义View:
package com.example.nostalgia.myapplication.view;
import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.Scroller;
import android.widget.TextView;
import com.example.nostalgia.myapplication.R;
import com.example.nostalgia.myapplication.Utils.DensityUtils;
import com.example.nostalgia.myapplication.bean.NewsInfo;
import java.util.List;
/**
* Created by Nostalgia on 2016/12/8.
* Title : 头条热点
*/
public class HomeScrollTopView extends LinearLayout {
private Scroller mScroller; //滚动实例
private int size = 0;
private List<NewsInfo> list; //存放数据集合
private final int DURING_TIME = 3000; //滚动延迟
private OnAdapterClickListener<NewsInfo> click;
Context context;
public HomeScrollTopView(Context context) {
super(context);
this.context = context;
init();
}
public HomeScrollTopView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
init();
}
private void init() {
mScroller = new Scroller(getContext());
}
/**
* 设置数据
*
* @param list
*/
public void setData(List<NewsInfo> list) {
this.list = list;
if (list != null) {
removeAllViews();
size = list.size();
for (int i = 0; i < size; i++) {
addContentView(i);
}
if (list.size() > 1) {
getLayoutParams().height = DensityUtils.dip2px(context, 40);//调节滚动数据的高度
// 滚动
cancelAuto();
mHandler.sendEmptyMessageDelayed(0, DURING_TIME);
smoothScrollBy(0, DensityUtils.dip2px(context, 40));
}
}
}
/**
* 设置列表点击事件
*
* @param click
*/
public void setClickListener(OnAdapterClickListener<NewsInfo> click) {
this.click = click;
}
/**
* 重置数据
*/
private void resetView() {
NewsInfo homeBuyHouseGuide = list.get(0);
list.remove(0);
list.add(homeBuyHouseGuide);
for (int i = 0; i < size; i++) {
addContentView(i);
}
}
/**
* 取消滚动
*/
public void cancelAuto() {
mHandler.removeMessages(0);
}
private void addContentView(final int position) {
ViewHolder mHolder;
if (position >= getChildCount()) {
mHolder = new ViewHolder();
View v = View.inflate(getContext(), R.layout.home_scrolltopview, null);
mHolder.biaoqianTv = (TextView) v.findViewById(R.id.tv_biaoqian);
mHolder.nameTv = (TextView) v.findViewById(R.id.tv);
v.setTag(mHolder);
addView(v, LayoutParams.MATCH_PARENT, DensityUtils.dip2px(context, 40));
} else {
mHolder = (ViewHolder) getChildAt(position).getTag();
}
final NewsInfo newsInfo = list.get(position);
if (!DensityUtils.isNullOrEmpty(newsInfo.tagname)) {
mHolder.biaoqianTv.setText(newsInfo.tagname);
} else {
mHolder.biaoqianTv.setVisibility(GONE);
}
if (!DensityUtils.isNullOrEmpty(newsInfo.title)) {
mHolder.nameTv.setText(newsInfo.title);
} else {
mHolder.nameTv.setVisibility(GONE);
}
mHolder.nameTv.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
if (click != null) {
click.onAdapterClick(null, newsInfo);
}
}
});
}
private class ViewHolder {
TextView nameTv;
TextView biaoqianTv;
}
Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
mHandler.removeMessages(0);
mHandler.sendEmptyMessageDelayed(0, DURING_TIME);
smoothScrollBy(0, DensityUtils.dip2px(context, 40));
resetView();
}
;
};
// 调用此方法设置滚动的相对偏移
public void smoothScrollBy(int dx, int dy) {
// 设置mScroller的滚动偏移量
mScroller.startScroll(mScroller.getFinalX(), 0, dx, dy, DURING_TIME);
invalidate();// 这里必须调用invalidate()才能保证computeScroll()会被调用,否则不一定会刷新界面,看不到滚动效果
}
@Override
public void computeScroll() {
// 先判断mScroller滚动是否完成
if (mScroller.computeScrollOffset()) {
// 这里调用View的scrollTo()完成实际的滚动
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
// 必须调用该方法,否则不一定能看到滚动效果
postInvalidate();
}
super.computeScroll();
}
public interface OnAdapterClickListener<T> {
public void onAdapterClick(View v, T t);
}
}
实体类:
package com.example.nostalgia.myapplication.bean;
import java.io.Serializable;
/**
* Created by
* Nostalgia
* on 2016/12/8.
*
* Title: 实体类
*/
public class NewsInfo implements Serializable {
private static final long serialVersionUID = 1L;
public String type;// 类型 根据type值做跳转使用
public String tagname;// 标签
public String title;// 显示标题
public String news_url;//跳转wap的信息url
public NewsInfo(String type,String tagname,String title,String news_url) {
super();
this.type = type ;
this.tagname = tagname ;
this.title = title ;
this.news_url = news_url ;
}
}
调用主类:
package com.example.nostalgia.myapplication;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.example.nostalgia.myapplication.bean.NewsInfo;
import com.example.nostalgia.myapplication.view.HomeScrollTopView;
import java.util.ArrayList;
/**
* Created by Nostalgia on 2016/12/8.
* Title : 轮播头条样例
*/
public class MainActivity extends Activity {
HomeScrollTopView topView;
LinearLayout ll_homescrolltopview;
private ArrayList<NewsInfo> newsInfoList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initData();
initOper();
}
private void initView() {
topView = (HomeScrollTopView) findViewById(R.id.homescrolltopview);
ll_homescrolltopview = (LinearLayout) findViewById(R.id.ll_homescrolltopview);
ll_homescrolltopview.setVisibility(View.GONE);
}
private void initData() {
if (newsInfoList.size() > 0) {
newsInfoList.clear();
}
for (int i = 0; i < 6; i++) {
newsInfoList.add(new NewsInfo("" + i, "标签" + i, "这里是测试标题" + i, ""));
}
/**
* 上面改成接口返回的数据填充到list中
*/
if (newsInfoList.size() < 1) {
ll_homescrolltopview.setVisibility(View.GONE);
} else {
ll_homescrolltopview.setVisibility(View.VISIBLE);
topView.setData(newsInfoList);
}
}
private void initOper() {
topView.setClickListener(new HomeScrollTopView.OnAdapterClickListener<NewsInfo>() {
@Override
public void onAdapterClick(View v, NewsInfo newsInfo) {
if ("1".equals(newsInfo.type)) {
Toast.makeText(MainActivity.this, "标签:" + newsInfo.tagname +"\n标题:" + newsInfo.title, Toast.LENGTH_SHORT).show();
} else if ("2".equals(newsInfo.type)) {
Toast.makeText(MainActivity.this, "标签:" + newsInfo.tagname + "\n标题:" + newsInfo.title, Toast.LENGTH_SHORT).show();
} else if ("3".equals(newsInfo.type)) {
Toast.makeText(MainActivity.this, "标签:" + newsInfo.tagname + "\n标题:" + newsInfo.title, Toast.LENGTH_SHORT).show();
} else if ("4".equals(newsInfo.type)) {
Toast.makeText(MainActivity.this, "标签:" + newsInfo.tagname + "\n标题:" + newsInfo.title, Toast.LENGTH_SHORT).show();
} else if ("5".equals(newsInfo.type)) {
Toast.makeText(MainActivity.this, "标签:" + newsInfo.tagname + "\n标题:" + newsInfo.title, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "标签:" + newsInfo.tagname + "\n标题:" + newsInfo.title, Toast.LENGTH_SHORT).show();
}
}
});
}
}
工具方法:
/**
* dp转px
*
* @param context
* @param
* @return
*/
public static int dip2px(Context context, float dpVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
dpVal, context.getResources().getDisplayMetrics());
}
/**
* 判断是否为空
*
* @param text
* @return
*/
public static boolean isNullOrEmpty(String text) {
if (text == null || "".equals(text.trim()) || text.trim().length() == 0
|| "null".equals(text.trim())) {
return true;
} else {
return false;
}
}
Demo代码已完整上传到CSDN: 点这里去下载