您的位置:首页 > 其它

仿 淘宝头条热点 天猫头条热点 京东头条热点的自定义view 实现

2016-12-08 12:39 441 查看
最近整理了一下在自己负责的项目中用到的一些自定义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 (n
99db
ewsInfoList.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:点这里去下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息