最近整理了一下在自己負責的項目中用到的一些自定義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:點這裏去下載