ListView個性化滑動指示器酷炫效果
前幾天看到有好多人搞了一個listView的一個指示特效。然後自己參考了一下
面對這樣的效果年會想起來幾種思路?
- 自定義scrollView+scrollBar
- 自定義ListView+自定義ScrollBar
- 自定義 RecycleView
- 自定義Behavior
- 自定義listView + PopuWindows
- 自定義ViewGroup
這幾種哪一種是最合適的呢?
分析
- 首先不看滑動彈出效果,一般來說自定義ListView+自定義ScrollBar是最合適的
- 自定義 RecycleView 多此一舉
- 自定義Behavior把問題簡單複雜話了
- 自定義scrollView+scrollBar需要重新構造ListView ,重寫onDraw,小題大作
- 自定義ViewGroup 過程太繁瑣
- 如果使用自定義listView + PopuWindows對scrollBar進行設定彈出效果,由於popupWindow是窗體,更不合適是現實出現一個氣泡和LISView的scrollBar試試監聽的結合。
- 首先我們確定的是:
- 自定義ListView
- 對ScrollBar進行監聽和操作
話不多少,還是上程式碼吧:
MyScrollbarListview.java:
/**
* 類功能描述:</br>
*
* @author yuyahao
* @version 1.0 </p> 修改時間:</br> 修改備註:</br>
*/
public class MyScrollbarListview extends ListView implements AbsListView.OnScrollListener {
private View mScrollPanelView;
private int mMeasureWidthSpect ;
private int mMeasureHeghtSpect ;
/**
* 定義y軸的滑動變數,在onScroll裡不斷去判斷和負值
*/
private int mScrollbarPanelPosition = 0;
private Animation mComeInAnimation = null;
private Animation mGoOutAnimation = null;
/**
*
* 定義指示器在Y軸的高度
*/
private int mThumbOffset = 0;
private int mLastPosition = - 1;
private OnPositionListener onPositionListener;
public MyScrollbarListview(Context context, AttributeSet attrs) {
super(context, attrs);
super.setOnScrollListener(this);
TypedArray typeArray = context.obtainStyledAttributes(attrs, R.styleable.MyScrollbarListview);
int LayoutId = -1,inAnimation = -1,outAnimation = -1;
if(typeArray != null){
LayoutId = typeArray.getResourceId(R.styleable.MyScrollbarListview_scrollBarPanel,-1);
inAnimation = typeArray.getResourceId(R.styleable.MyScrollbarListview_scrollBarComeInAnamation,-1);
outAnimation = typeArray.getResourceId(R.styleable.MyScrollbarListview_scrollBarGoOutAnamation,-1);
typeArray.recycle();
}
if(inAnimation != -1){
mComeInAnimation = AnimationUtils.loadAnimation(context,inAnimation);
}else{
mComeInAnimation = AnimationUtils.loadAnimation(context,R.anim.transation_animation_left);
}
if(outAnimation != -1){
mGoOutAnimation = AnimationUtils.loadAnimation(context,outAnimation);
}else{
mGoOutAnimation = AnimationUtils.loadAnimation(context,R.anim.transation_animation_right);
}
setMyPanelViewId(LayoutId);
int drutionMmillis = ViewConfiguration.getScrollBarFadeDuration();//得到系統預設的淡出的時間
mGoOutAnimation.setDuration(drutionMmillis);
mGoOutAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
if(mScrollPanelView != null){
mScrollPanelView.setVisibility(GONE);
}
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
}
private void setMyPanelViewId(int layoutId){
mScrollPanelView = LayoutInflater.from(getContext()).inflate(layoutId,this,false);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);//先測量父容器,在對子佈局進行測量
if(mScrollPanelView != null && getAdapter() != null){
measureChild(mScrollPanelView,widthMeasureSpec,heightMeasureSpec);
this.mMeasureWidthSpect = widthMeasureSpec;
this.mMeasureHeghtSpect = heightMeasureSpec;
requestLayout();
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
if(mScrollPanelView != null){
int left = getMeasuredWidth() - mScrollPanelView.getMeasuredWidth() - mScrollPanelView.
getVerticalScrollbarWidth();
mScrollPanelView.layout(left,
mScrollbarPanelPosition,
left + mScrollPanelView.getMeasuredWidth(),
mScrollbarPanelPosition +mScrollPanelView.getMeasuredHeight()
);
}
}
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
//在ViewGroup繪製的事後
if(mScrollPanelView != null && mScrollPanelView.getVisibility() == VISIBLE){
drawChild(canvas,mScrollPanelView,getDrawingTime());
}
}
@Override
public void onScrollStateChanged(AbsListView absListView, int i) {
}
@Override
public void onScroll(AbsListView absListView, int firstItem, int visisbleTotle, int allTotle) {
//監聽系統滑塊在那個位置,設定總結的位置
//監聽回撥---》去設定位置---》position
if(mScrollPanelView != null && onPositionListener != null){
/**
* computeHorizontalScrollExtent //滑動條在縱向範圍內 自身的高度的幅度--》放大後的
* computeHorizontalScrollOffset //滑動條在縱向 的位置--》放大後的
* computeHorizontalScrollRange //比如0-5000,滑動範圍--》放大後的
*/
//利用 平行線分線段成比例定理進行 取值
//1.劃片的高度 / listView的高度 = computeHorizontalScrollExtent / computeHorizontalScrollRange
int height = Math.round(1.0f * computeVerticalScrollExtent()* getMeasuredHeight()/
computeVerticalScrollRange() );
mThumbOffset = (int) (1.0f * computeVerticalScrollOffset() * height/
computeVerticalScrollExtent() );
int left2 = getMeasuredWidth() - mScrollPanelView.getMeasuredWidth() -
mScrollPanelView.getVerticalScrollbarWidth();
//2得到 滑塊Y正中央的位置Y
mThumbOffset = mThumbOffset + height/ 2;
mScrollbarPanelPosition = mThumbOffset - height/ 2;
mScrollPanelView.layout(
left2,
mScrollbarPanelPosition,
left2 + mScrollPanelView.getMeasuredWidth(),
mScrollbarPanelPosition +mScrollPanelView.getMeasuredHeight()
);
for (int j = 0; j < getChildCount(); j++) {
View view = getChildAt(j);
if(view != null){
if(mThumbOffset + height/2 > view.getTop() && mThumbOffset + height/2 < view.getBottom()){
if(mLastPosition != firstItem + j){
mLastPosition = firstItem + j;
if(onPositionListener != null){
onPositionListener.myPositionChanged(mLastPosition,null,this,mScrollPanelView);
//避免寬度發生改變,重新測量其大小
measureChild(mScrollPanelView,mMeasureWidthSpect,mMeasureHeghtSpect);
}
}
}
}
}
}
}
@Override
protected boolean awakenScrollBars(int startDelay, boolean invalidate) {
boolean isWake = super.awakenScrollBars(startDelay, invalidate);
if(isWake && mScrollPanelView != null){
if(mScrollPanelView.getVisibility() == GONE){
mScrollPanelView.setVisibility(VISIBLE);
if(mComeInAnimation != null){
mScrollPanelView.startAnimation(mComeInAnimation);
}
}
mHandler.removeCallbacksAndMessages(null);
mHandler.removeCallbacks(runTask);
//設定小時
mHandler.postAtTime(runTask,startDelay+AnimationUtils.currentAnimationTimeMillis());
}else{
mScrollPanelView.setVisibility(GONE);
if(mComeInAnimation != null){
mScrollPanelView.startAnimation(mGoOutAnimation);
}
}
return isWake;
}
private Handler mHandler = new Handler();
private Runnable runTask = new Runnable() {
@Override
public void run() {
if(mGoOutAnimation != null){
mScrollPanelView.startAnimation(mGoOutAnimation);
}
}
};
public interface OnPositionListener{
void myPositionChanged(int position,Student student,MyScrollbarListview myScrollbarListView,
View mScrollPanelView);
}
public void setOnPositionListener(OnPositionListener onPositionListener){
this.onPositionListener = onPositionListener;
}
}
入口類MainActivity.java
/**
* 類功能描述:</br>
*
* @author yuyahao
* @version 1.0 </p> 修改時間:</br> 修改備註:</br>
*/
public class MainActivity extends AppCompatActivity {
@Bind(R.id.lv_customser_zoomscroll)
MyScrollbarListview lv_customser_zoomscroll;
private List<Student> list = new ArrayList<>();
private ScrollListViewAdapter2 scrollListViewAdapter2;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initData();
}
protected void initData() {
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
list.addAll(ServiceData.getStudentList());
lv_customser_zoomscroll.setOnPositionListener(new MyScrollbarListview.OnPositionListener() {
@Override
public void myPositionChanged(int position, Student student, MyScrollbarListview
myScrollbarListView, View mScrollPanelView) {
Student student1 = list.get(position);
TextView tv = (TextView) mScrollPanelView.findViewById(R.id.iv_name);
TextView tv_lessons = (TextView) mScrollPanelView.findViewById(R.id.tv_lessons);
tv.setText("" + student1.getName()+" "+" level: "+position);
tv_lessons.setText("科目: "+student1.getList().get(0).getPerListenceName());
}
});
scrollListViewAdapter2 = new ScrollListViewAdapter2(MainActivity.this,list);
lv_customser_zoomscroll.setAdapter(scrollListViewAdapter2);
}
}
佈局.xml:
<?xml version="1.0" encoding="utf-8" ?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
xmlns:app ="http://schemas.android.com/apk/res/cv.yyh.com.myscrollbarlistview"
android:layout_height="match_parent">
<cv.yyh.com.myscrollbarlistview.view.MyScrollbarListview
android:layout_width="match_parent"
android:layout_height="match_parent"
android:choiceMode="singleChoice"
android:scrollbarThumbVertical="@drawable/listbar"
android:id="@+id/lv_customser_zoomscroll"
app:scrollBarPanel="@layout/panel_text"
app:scrollBarComeInAnamation="@anim/transation_animation_left"
app:scrollBarGoOutAnamation="@anim/transation_animation_right"
/>
</LinearLayout>
如果你覺得此文對您有所幫助,歡迎入群 QQ交流群 :232203809
微信公眾號:終端研發部
(歡迎關注學習和交流)
相關推薦
ListView個性化滑動指示器酷炫效果
前幾天看到有好多人搞了一個listView的一個指示特效。然後自己參考了一下 面對這樣的效果年會想起來幾種思路? - 自定義scrollView+scrollBar - 自定義ListView+自定義ScrollBar - 自定義 RecycleVi
微信小程序左右滑動切換圖片酷炫效果(附效果)
bin select ans for image pac psi border als 開門見山,先上效果吧!感覺可以的用的上的再往下看。 心動嗎?那就繼續往下看! 先上頁面結構吧,也就是wxml文件,其實可以理解成微信自己封裝過的html,這個不多說了,不懂
微信小程式左右滑動切換圖片酷炫效果(附效果)
開門見山,先上效果吧!感覺可以的用的上的再往下看。(動圖網址) 心動嗎?那就繼續往下看! 先上頁面結構吧,也就是wxml檔案,其實可以理解成微信自己封裝過的html,這個不多說了,不懂也沒必要往下看了。 1<scroll-view class="scroll-view_H" scro
viewpager的酷炫效果的實現(同時顯示出多個頁面)
1.在佈局中通過給根佈局和ViewPager控制元件同時設定一個屬性即可:android:clipChildren="false" 舉例: <LinearLayout xmlns:android="http://schemas.android.com/apk/res
Duang,Duang,H5 +酷炫效果+乾貨,此時不收更待何時
現在市面上有一大批H5頁面模板製作工具,誠然,他們方便了很多非專業設計師設計製作H5頁面。但是,很多模板工具上的作品大部分還停留在左飛入右飛出的初級境界,看多了真心有些膩,動效如無美感還不如看靜態的。 那H5裡有哪些高階動效了?小思仔細體驗了國內所有優秀H5頁面作品,
自定義開關View的酷炫效果(ButtonView)
不多說先看圖 寫在前頭 最近在看到的一個按鈕動畫,覺得以後在專案中遇到的可能性挺大的,閒的無聊實現了下,程式碼貼在下面,還請各位大神多多指正,互相學習! 程式碼實現 做了比較多的註釋,是自己的學習,也是提供給看的人更清楚明瞭。 publ
Android控制元件開發之Gallery3D酷炫效果 瀏覽圖片
效果網上已經很多人做出來了,只是這次需要用到,所以自己也實踐了一下(這裡例子我也是根據網上一些資料編寫)。特下面針對一些關鍵程式碼進行簡要說明,需要做這方面東西的朋友可以看看。這篇文章是實用性文章,理論分析不多。
使用NestedScrollView+ViewPager+RecyclerView+SmartRefreshLayout打造酷炫下拉視差效果並解決各種滑動沖突
magic refresh gen view設置 需要 如果 .cn int bre 使用NestedScrollView+ViewPager+RecyclerView+SmartRefreshLayout打造酷炫下拉視差效果並解決各種沖突 如果你還在為處理滑動沖突而發愁,
Android ViewPager酷炫的卡片滑動效果
一、效果圖 二、實現程式碼 MainActivity.java package com.github.rubensousa.viewpagercards; import android.support.v4.view.ViewPager; imp
使用NestedScrollView+ViewPager+RecyclerView+SmartRefreshLayout打造酷炫下拉視差效果並解決各種滑動衝突
如果你還在為處理滑動衝突而發愁,那麼你需要靜下心來看看這邊文章,如果你能徹底理解這篇文章中使用的技術,那麼,一切滑動衝突的問題解決起來就輕而易舉了:先扔一個最終實現的效果圖先分析下效果圖中實現的功能點頂部下拉時背景圖形成視差效果上拉時標題欄透明切換顯示底部實現TabLayout+ViewPager+Fragm
超級酷炫的懸浮效果
超級 ren parent view -c hover 來吧 技術 com 今天在奇舞周刊上看到了一篇文章,看到其酷炫的效果,自己忍不住試了一下,小夥伴們都驚呆了。。。這個效果是將光標移動到按鈕上的不同位置產生的彩色漸變。 代碼如下: <!DOCTYPE
react-native-page-scrollview 的使用方法(實現酷炫的分頁輪播效果)
ota interview native cte ren 意圖 let change sets react-native-page-scrollview 對ScrollView的封裝,可以很方便的實現水平,垂直分頁輪播效果.而且可以自定義分頁寬高,和側邊View的旋轉,透明
如何製作電子相簿發到微信?快速上手教程,效果酷炫刷爆朋友圈
如何製作電子相簿發到微信?現在朋友圈出現了很多旅遊、兒童、婚禮等主題的電子相簿,效果好看,能獲得超多贊。 今天就教大家用數碼大師,快速做出一個很好看的微信電子相簿。朋友圈獲得超多讚的效果,在這裡可以直接運用,還能自己DIY各種風格的電子相簿。匯出高清的電子相簿後可以傳到微信朋友圈、視訊網
照片動感影集製作軟體哪個好?如何快速製作精美、酷炫的效果?
把照片做成動感影集是現在非常流行的照片分享方式。抖音上獲得百萬讚的照片動感影集,把照片運用上精美酷炫效果後做成的視訊。那麼,照片動感影集製作軟體哪個好?怎麼才能快速上手,製作一個效果高大上的動感影集? 大家可以試試國內比較流行的數碼大師,功能還是很齊全的。製作照片動感影集可以直接利用數碼大
Android酷炫動畫效果之進度載入動畫
package com.eftimoff.androipathview; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; import android
Android 常用效果(各種進度條,酷炫loading動畫,火箭升空,撒花以及趨勢圖)
最近時間比較充裕一些,總結了下幾個專案用到的ui效果,在這邊共享給大家,也給自己做個記錄(後面會有demo貼出). 主要是以下幾種ui效果: 進度條多種展示 開源loading動畫 火箭升空 撒花
WordPress評論框配置炫酷打字效果
大家也發現了,給本站評論的時候加了很炫酷的效果,那麼是不是也想來一發呢?這個效果我最初看到是去年idea的一個外掛,一直沒留意,最近發現很多朋友都配置了這個炫酷的效果,那麼我也是不能落後啊。不多說廢話了,直接切入主題。本效果需要一個JS檔案,點選訪問。下載下來以後,上傳到主題的JS位置,或者你習慣的位置。本站
Android 使用NineOldAndroids實現絢麗的ListView左右滑動刪除Item效果
今天還是給大家帶來自定義控制元件的編寫,自定義一個ListView的左右滑動刪除Item的效果,這個效果之前已經實現過了,有興趣的可以看下Android 使用Scroller實現絢麗的ListView左右滑動刪除Item效果,之前使用的是滑動類Scroller來實現的,但是看
使用css3 var變數 實現酷炫button效果
css3 var 變數定義 無意中發現 css3的擁有一個自定義屬性的功能,利用這個功能,我們可以實現灰常牛逼的功能。如圖: css自定義變數的語法是 --* 取名規則也很廣,除了$、[、^、(、%都可以取,甚至可以取中文名。。 舉個栗子:
Android開發之實現最簡單最酷炫的3D圖片瀏覽效果(一)
一、原理 整體實現是以手機螢幕的正中間位置為對稱軸,位於正中間的圖片顯示最大,也最亮,同時左右兩邊的圖片以最中間位置為對稱軸,分別旋轉對應的角度,同時亮度調整為適當的比例,已達到對稱的效果。具體的3D瀏覽圖片效果,我是通過自定義Gallery來實現的,建立一個類Galler