日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

android camera滑动,Android怎么实现小米相机底部滑动指示器

發(fā)布時間:2025/3/8 52 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android camera滑动,Android怎么实现小米相机底部滑动指示器 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Android怎么實現(xiàn)小米相機底部滑動指示器

發(fā)布時間:2021-04-15 14:39:38

來源:億速云

閱讀:94

作者:小新

這篇文章給大家分享的是有關Android怎么實現(xiàn)小米相機底部滑動指示器的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

先上一張圖看下效果:

主要實現(xiàn)功能有:

1.支持左右滑動,每次滑動一個tab

2.支持tab點擊,直接跳到對應tab

3.選中的tab一直處于居中位置

4.支持部分UI自定義(大家可根據需要自己改動)

5.tab點擊回調

6.內置Tab接口,放入的內容需要實現(xiàn)Tab接口

7.設置預選中tabpublic?class?CameraIndicator?extends?LinearLayout?{

//?當前選中的位置索引

private?int?currentIndex;

//tabs集合

private?Tab[]?tabs;

//?利用Scroller類實現(xiàn)最終的滑動效果

public?Scroller?mScroller;

//滑動執(zhí)行時間(ms)

private?int?mDuration?=?300;

//選中text的顏色

private?int?selectedTextColor?=?0xffffffff;

//未選中的text的顏色

private?int?normalTextColor?=?0xffffffff;

//選中的text的背景

private?Drawable?selectedTextBackgroundDrawable;

private?int?selectedTextBackgroundColor;

private?int?selectedTextBackgroundResources;

//是否正在滑動

private?boolean?isScrolling?=?false;

private?int?onLayoutCount?=?0;

public?CameraIndicator(Context?context)?{

this(context,?null);

}

public?CameraIndicator(Context?context,?@Nullable?AttributeSet?attrs)?{

this(context,?attrs,?0);

}

public?CameraIndicator(Context?context,?@Nullable?AttributeSet?attrs,?int?defStyleAttr)?{

super(context,?attrs,?defStyleAttr);

mScroller?=?new?Scroller(context);

}

@Override

protected?void?onMeasure(int?widthMeasureSpec,?int?heightMeasureSpec)?{

super.onMeasure(widthMeasureSpec,?heightMeasureSpec);

int?widthMode?=?MeasureSpec.getMode(widthMeasureSpec);

int?widthSize?=?MeasureSpec.getSize(widthMeasureSpec);

int?heightMode?=?MeasureSpec.getMode(heightMeasureSpec);

int?heightSize?=?MeasureSpec.getSize(heightMeasureSpec);

//測量所有子元素

measureChildren(widthMeasureSpec,?heightMeasureSpec);

//處理wrap_content的情況

int?width?=?0;

int?height?=?0;

if?(getChildCount()?==?0)?{

setMeasuredDimension(0,?0);

}?else?if?(widthMode?==?MeasureSpec.AT_MOST?&&?heightMode?==?MeasureSpec.AT_MOST)?{

for?(int?i?=?0;?i?

View?child?=?getChildAt(i);

width?+=??child.getMeasuredWidth();

height?=?Math.max(height,?child.getMeasuredHeight());

}

setMeasuredDimension(width,?height);

}?else?if?(widthMode?==?MeasureSpec.AT_MOST)?{

for?(int?i?=?0;?i?

View?child?=?getChildAt(i);

width?+=??child.getMeasuredWidth();

}

setMeasuredDimension(width,?heightSize);

}?else?if?(heightMode?==?MeasureSpec.AT_MOST)?{

for?(int?i?=?0;?i?

View?child?=?getChildAt(i);

height?=?Math.max(height,?child.getMeasuredHeight());

}

setMeasuredDimension(widthSize,?height);

}?else?{

//如果自定義ViewGroup之初就已確認該ViewGroup寬高都是match_parent,那么直接設置即可

setMeasuredDimension(widthSize,?heightSize);

}

}

@Override

protected?void?onLayout(boolean?changed,?int?l,?int?t,?int?r,?int?b)?{

//給選中text的添加背景會多次進入onLayout,會導致位置有問題,暫未解決

if?(onLayoutCount?>?0)?{

return;

}

onLayoutCount++;

int?counts?=?getChildCount();

int?childLeft?=?0;

int?childRight?=?0;

int?childTop?=?0;

int?childBottom?=?0;

//居中顯示

int?widthOffset?=?0;

//計算最左邊的子view距離中心的距離

for?(int?i?=?0;?i?

View?childView?=?getChildAt(i);

widthOffset?+=?childView.getMeasuredWidth()?+?getMargins(childView).get(0)+getMargins(childView).get(2);

}

//計算出每個子view的位置

for?(int?i?=?0;?i?

View?childView?=?getChildAt(i);

childView.setOnClickListener(v?->?moveTo(v));

if?(i?!=?0)?{

View?preView?=?getChildAt(i?-?1);

childLeft?=?preView.getRight()?+getMargins(preView).get(2)+?getMargins(childView).get(0);

}?else?{

childLeft?=?(getWidth()?-?getChildAt(currentIndex).getMeasuredWidth())?/?2?-?widthOffset;

}

childRight?=?childLeft?+?childView.getMeasuredWidth();

childTop?=?(getHeight()?-?childView.getMeasuredHeight())?/?2;

childBottom?=?(getHeight()?+?childView.getMeasuredHeight())?/?2;

childView.layout(childLeft,?childTop,?childRight,?childBottom);

}

TextView?indexText?=?(TextView)?getChildAt(currentIndex);

changeSelectedUIState(indexText);

}

private?List?getMargins(View?view)?{

LayoutParams?params?=?(LayoutParams)?view.getLayoutParams();

List?listMargin?=?new?ArrayList();

listMargin.add(params.leftMargin);

listMargin.add(params.topMargin);

listMargin.add(params.rightMargin);

listMargin.add(params.bottomMargin);

return?listMargin;

}

@Override

public?void?computeScroll()?{

if?(mScroller.computeScrollOffset())?{

//?滑動未結束,內部使用scrollTo方法完成實際滑動

scrollTo(mScroller.getCurrX(),?mScroller.getCurrY());

invalidate();

}?else?{

//滑動完成

isScrolling?=?false;

if?(listener?!=?null)?{

listener.onChange(currentIndex,tabs[currentIndex]);

}

}

super.computeScroll();

}

/**

*?改變選中TextView的顏色

*

*?@param?currentIndex?滑動之前選中的那個

*?@param?nextIndex????滑動之后選中的那個

*/

public?final?void?scrollToNext(int?currentIndex,?int?nextIndex)?{

TextView?selectedText?=?(TextView)?getChildAt(currentIndex);

if?(selectedText?!=?null)?{

selectedText.setTextColor(normalTextColor);

selectedText.setBackground(null);

}

selectedText?=?(TextView)?getChildAt(nextIndex);

if?(selectedText?!=?null)?{

changeSelectedUIState(selectedText);

}

}

private?void?changeSelectedUIState(TextView?view)?{

view.setTextColor(selectedTextColor);

if?(selectedTextBackgroundDrawable?!=?null)?{

view.setBackground(selectedTextBackgroundDrawable);

}

if?(selectedTextBackgroundColor?!=?0)?{

view.setBackgroundColor(selectedTextBackgroundColor);

}

if?(selectedTextBackgroundResources?!=?0)?{

view.setBackgroundResource(selectedTextBackgroundResources);

}

}

/**

*?向右滑一個

*/

public?void?moveToRight()?{

moveTo(getChildAt(currentIndex?-?1));

}

/**

*?向左滑一個

*/

public?void?moveToLeft()?{

moveTo(getChildAt(currentIndex?+?1));

}

/**

*?滑到目標view

*

*?@param?view?目標view

*/

private?void?moveTo(View?view)?{

for?(int?i?=?0;?i?

if?(view?==?getChildAt(i))?{

if?(i?==?currentIndex)?{

//不移動

break;

}?else?if?(i?

//向右移

if?(isScrolling)?{

return;

}

isScrolling?=?true;

int?dx?=?getChildAt(currentIndex).getLeft()?-?view.getLeft()?+?(getChildAt(currentIndex).getMeasuredWidth()?-?view.getMeasuredWidth())?/?2;

//這里使用scroll會使滑動更平滑不卡頓,scroll會根據起點、終點及時間計算出每次滑動的距離,其內部有一個插值器

mScroller.startScroll(getScrollX(),?0,?-dx,?0,?mDuration);

scrollToNext(currentIndex,?i);

setCurrentIndex(i);

invalidate();

}?else?if?(i?>?currentIndex)?{

//向左移

if?(isScrolling)?{

return;

}

isScrolling?=?true;

int?dx?=?view.getLeft()?-?getChildAt(currentIndex).getLeft()?+?(view.getMeasuredWidth()?-?getChildAt(currentIndex).getMeasuredWidth())?/?2;

mScroller.startScroll(getScrollX(),?0,?dx,?0,?mDuration);

scrollToNext(currentIndex,?i);

setCurrentIndex(i);

invalidate();

}

}

}

}

/**

*?設置tabs

*

*?@param?tabs

*/

public?void?setTabs(Tab...?tabs)?{

this.tabs?=?tabs;

//暫時不通過layout布局添加textview

if?(getChildCount()>0){

removeAllViews();

}

for?(Tab?tab?:?tabs)?{

TextView?textView?=?new?TextView(getContext());

textView.setText(tab.getText());

textView.setTextSize(14);

textView.setTextColor(selectedTextColor);

textView.setPadding(dp2px(getContext(),5),?dp2px(getContext(),2),?dp2px(getContext(),5),dp2px(getContext(),2));

LayoutParams?layoutParams=?new?LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);

layoutParams.rightMargin=dp2px(getContext(),2.5f);

layoutParams.leftMargin=dp2px(getContext(),2.5f);

textView.setLayoutParams(layoutParams);

addView(textView);

}

}

public?int?getCurrentIndex()?{

return?currentIndex;

}

//設置默認選中第幾個

public?void?setCurrentIndex(int?currentIndex)?{

this.currentIndex?=?currentIndex;

}

//設置滑動時間

public?void?setDuration(int?mDuration)?{

this.mDuration?=?mDuration;

}

public?void?setSelectedTextColor(int?selectedTextColor)?{

this.selectedTextColor?=?selectedTextColor;

}

public?void?setNormalTextColor(int?normalTextColor)?{

this.normalTextColor?=?normalTextColor;

}

public?void?setSelectedTextBackgroundDrawable(Drawable?selectedTextBackgroundDrawable)?{

this.selectedTextBackgroundDrawable?=?selectedTextBackgroundDrawable;

}

public?void?setSelectedTextBackgroundColor(int?selectedTextBackgroundColor)?{

this.selectedTextBackgroundColor?=?selectedTextBackgroundColor;

}

public?void?setSelectedTextBackgroundResources(int?selectedTextBackgroundResources)?{

this.selectedTextBackgroundResources?=?selectedTextBackgroundResources;

}

public?interface?OnSelectedChangedListener?{

void?onChange(int?index,?Tab?tag);

}

private?OnSelectedChangedListener?listener;

public?void?setOnSelectedChangedListener(OnSelectedChangedListener?listener)?{

if?(listener?!=?null)?{

this.listener?=?listener;

}

}

private?int?dp2px(Context?context,?float?dpValue)?{

DisplayMetrics?metrics?=?context.getResources().getDisplayMetrics();

return?(int)?(metrics.density?*?dpValue?+?0.5F);

}

public?interface?Tab{

String?getText();

}

private?float?startX?=?0f;

@Override

public?boolean?onTouchEvent(MotionEvent?event)?{

if?(event.getAction()?==?MotionEvent.ACTION_DOWN)?{

startX?=?event.getX();

}

if?(event.getAction()?==?MotionEvent.ACTION_UP)?{

float?endX?=?event.getX();

//向左滑條件

if?(endX?-?startX?>?50?&&?currentIndex?>?0)?{

moveToRight();

}

if?(startX?-?endX?>?50?&&?currentIndex?

moveToLeft();

}

}

return?true;

}

@Override

public?boolean?onInterceptTouchEvent(MotionEvent?event)?{

if?(event.getAction()?==?MotionEvent.ACTION_DOWN)?{

startX?=?event.getX();

}

if?(event.getAction()?==?MotionEvent.ACTION_UP)?{

float?endX?=?event.getX();

//向左滑條件

if?(Math.abs(startX-endX)>50){

onTouchEvent(event);

}

}

return?super.onInterceptTouchEvent(event);

}

}

在Activity或fragment中使用private?var?tabs?=?listOf("慢動作",?"短視頻",?"錄像",?"拍照",?"108M",?"人像",?"夜景",?"萌拍",?"全景",?"專業(yè)")

lateinit?var??imageAnalysis:ImageAnalysis

override?fun?initView()?{

//實現(xiàn)了CameraIndicator.Tab的對象

val?map?=?tabs.map?{

CameraIndicator.Tab?{?it?}

}?.toTypedArray()??:?arrayOf()

//將tab集合設置給cameraIndicator,(binding.cameraIndicator即xml布局里的控件)

binding.cameraIndicator.setTabs(*map)

//默認選中??拍照

binding.cameraIndicator.currentIndex?=?3

//點擊某個tab的回調

binding.cameraIndicator.setSelectedTextBackgroundResources(R.drawable.selected_text_bg)

binding.cameraIndicator.setOnSelectedChangedListener?{?index,?tag?->

Toast.makeText(this,tag.text,Toast.LENGTH_SHORT).show()

}

}

感謝各位的閱讀!關于“Android怎么實現(xiàn)小米相機底部滑動指示器”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

總結

以上是生活随笔為你收集整理的android camera滑动,Android怎么实现小米相机底部滑动指示器的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。