1. <ul id="0c1fb"></ul>

      <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
      <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区

      RELATEED CONSULTING
      相關(guān)咨詢
      選擇下列產(chǎn)品馬上在線溝通
      服務(wù)時間:8:30-17:00
      你可能遇到了下面的問題
      關(guān)閉右側(cè)工具欄

      新聞中心

      這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
      Android實現(xiàn)3D層疊式卡片圖片展示

      本文實例為大家分享了Android實現(xiàn)3D層疊式卡片圖片展示的具體代碼,供大家參考,具體內(nèi)容如下

      10年積累的網(wǎng)站建設(shè)、網(wǎng)站制作經(jīng)驗,可以快速應(yīng)對客戶對網(wǎng)站的新想法和需求。提供各種問題對應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識你,你也不認(rèn)識我。但先網(wǎng)站設(shè)計制作后付款的網(wǎng)站建設(shè)流程,更有西塞山免費網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

      先看效果

      Android實現(xiàn)3D層疊式卡片圖片展示

      好了效果看了,感興趣的往下看哦!

      整體實現(xiàn)思路

      1、重寫RelativeLayout 實現(xiàn) 鎖定寬高比例的 RelativeLayout

      2、自定義一個支持滑動的面板 繼承 ViewGroup

      3、卡片View繪制

      4、頁面中使用布局

      首先為了更好的展示圖片我們重寫一下 RelativeLayout 編寫一個鎖定寬高比例的 RelativeLayout

      AutoScaleRelativeLayout

      public class AutoScaleRelativeLayout extends RelativeLayout {
       //寬高比例
       private float widthHeightRate = 0.35f;
      
       public AutoScaleRelativeLayout(Context context) {
        this(context, null);
       }
      
       public AutoScaleRelativeLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
       }
      
       public AutoScaleRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //通過布局獲取寬高比例
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.card, 0, 0);
        widthHeightRate = a.getFloat(R.styleable.card_widthHeightRate, widthHeightRate);
        a.recycle();
       }
      
       @Override
       protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
      
        // 調(diào)整高度
        int width = getMeasuredWidth();
        int height = (int) (width * widthHeightRate);
        ViewGroup.LayoutParams lp = getLayoutParams();
        lp.height = height;
        setLayoutParams(lp);
       }
      }

      這樣我們就編寫好了我們想要的父布局

      使用方法

      
      
        
      
        
      
      

      接下來就是主要布局,也就是展示圖片的布局了

      為了實現(xiàn)滑動我們編寫一個支持滑動的畫板

      //事件處理
       @Override
       public boolean dispatchTouchEvent(MotionEvent ev) {
        int action = ev.getActionMasked();
        // 按下時保存坐標(biāo)信息
        if (action == MotionEvent.ACTION_DOWN) {
         this.downPoint.x = (int) ev.getX();
         this.downPoint.y = (int) ev.getY();
        }
        return super.dispatchTouchEvent(ev);
       }
      
       /* touch事件的攔截與處理都交給mDraghelper來處理 */
       @Override
       public boolean onInterceptTouchEvent(MotionEvent ev) {
        boolean shouldIntercept = mDragHelper.shouldInterceptTouchEvent(ev);
        boolean moveFlag = moveDetector.onTouchEvent(ev);
        int action = ev.getActionMasked();
        if (action == MotionEvent.ACTION_DOWN) {
         // ACTION_DOWN的時候就對view重新排序
         if (mDragHelper.getViewDragState() == ViewDragHelper.STATE_SETTLING) {
          mDragHelper.abort();
         }
         orderViewStack();
      
         // 保存初次按下時arrowFlagView的Y坐標(biāo)
         // action_down時就讓mDragHelper開始工作,否則有時候?qū)е庐惓?   mDragHelper.processTouchEvent(ev);
        }
      
        return shouldIntercept && moveFlag;
       }
      
       @Override
       public boolean onTouchEvent(MotionEvent e) {
        try {
         // 統(tǒng)一交給mDragHelper處理,由DragHelperCallback實現(xiàn)拖動效果
         // 該行代碼可能會拋異常,正式發(fā)布時請將這行代碼加上try catch
         mDragHelper.processTouchEvent(e);
        } catch (Exception ex) {
         ex.printStackTrace();
        }
        return true;
       }
       //計算
       @Override
       protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        measureChildren(widthMeasureSpec, heightMeasureSpec);
        int maxWidth = MeasureSpec.getSize(widthMeasureSpec);
        int maxHeight = MeasureSpec.getSize(heightMeasureSpec);
        setMeasuredDimension(
          resolveSizeAndState(maxWidth, widthMeasureSpec, 0),
          resolveSizeAndState(maxHeight, heightMeasureSpec, 0));
      
        allWidth = getMeasuredWidth();
        allHeight = getMeasuredHeight();
       }
       //定位
       @Override
       protected void onLayout(boolean changed, int left, int top, int right,
             int bottom) {
        // 布局卡片view
        int size = viewList.size();
        for (int i = 0; i < size; i++) {
         View viewItem = viewList.get(i);
         int childHeight = viewItem.getMeasuredHeight();
         int viewLeft = (getWidth() - viewItem.getMeasuredWidth()) / 2;
         viewItem.layout(viewLeft, itemMarginTop, viewLeft + viewItem.getMeasuredWidth(), itemMarginTop + childHeight);
         int offset = yOffsetStep * i;
         float scale = 1 - SCALE_STEP * i;
         if (i > 2) {
          // 備用的view
          offset = yOffsetStep * 2;
          scale = 1 - SCALE_STEP * 2;
         }
      
         viewItem.offsetTopAndBottom(offset);
         viewItem.setScaleX(scale);
         viewItem.setScaleY(scale);
        }
      
        // 布局底部按鈕的View
        if (null != bottomLayout) {
         int layoutTop = viewList.get(0).getBottom() + bottomMarginTop;
         bottomLayout.layout(left, layoutTop, right, layoutTop
           + bottomLayout.getMeasuredHeight());
        }
      
        // 初始化一些中間參數(shù)
        initCenterViewX = viewList.get(0).getLeft();
        initCenterViewY = viewList.get(0).getTop();
        childWith = viewList.get(0).getMeasuredWidth();
       }
        //onFinishInflate 當(dāng)View中所有的子控件均被映射成xml后觸發(fā)
       @Override
       protected void onFinishInflate() {
        super.onFinishInflate();
        // 渲染完成,初始化卡片view列表
        viewList.clear();
        int num = getChildCount();
        for (int i = num - 1; i >= 0; i--) {
         View childView = getChildAt(i);
         if (childView.getId() == R.id.card_bottom_layout) {
          bottomLayout = childView;
          initBottomLayout();
         } else {
          // for循環(huán)取view的時候,是從外層往里取
          CardItemView viewItem = (CardItemView) childView;
          viewItem.setParentView(this);
          viewItem.setTag(i + 1);
          viewItem.maskView.setOnClickListener(btnListener);
          viewList.add(viewItem);
         }
        }
      
        CardItemView bottomCardView = viewList.get(viewList.size() - 1);
        bottomCardView.setAlpha(0);
       }

      卡片View繪制

      private void initSpring() {
        SpringConfig springConfig = SpringConfig.fromBouncinessAndSpeed(15, 20);
        SpringSystem mSpringSystem = SpringSystem.create();
        springX = mSpringSystem.createSpring().setSpringConfig(springConfig);
        springY = mSpringSystem.createSpring().setSpringConfig(springConfig);
      
        springX.addListener(new SimpleSpringListener() {
         @Override
         public void onSpringUpdate(Spring spring) {
          int xPos = (int) spring.getCurrentValue();
          setScreenX(xPos);
          parentView.onViewPosChanged(CardItemView.this);
         }
        });
      
        springY.addListener(new SimpleSpringListener() {
         @Override
         public void onSpringUpdate(Spring spring) {
          int yPos = (int) spring.getCurrentValue();
          setScreenY(yPos);
          parentView.onViewPosChanged(CardItemView.this);
         }
        });
       }
       //裝載數(shù)據(jù)
       public void fillData(CardDataItem itemData) {
        Glide.with(getContext()).load(itemData.imagePath).into(imageView);
      
      
       }
       /**
        * 動畫移動到某個位置
        */
       public void animTo(int xPos, int yPos) {
        setCurrentSpringPos(getLeft(), getTop());
        springX.setEndValue(xPos);
        springY.setEndValue(yPos);
       }
      
       /**
        * 設(shè)置當(dāng)前spring位置
        */
       private void setCurrentSpringPos(int xPos, int yPos) {
        springX.setCurrentValue(xPos);
        springY.setCurrentValue(yPos);
       }

      接下來我們需要使用它 編寫Fragment布局

      <?xml version="1.0" encoding="utf-8"?>
      
      
      
      
       
      
        
      
         

      代碼中的使用

      private void initView(View rootView) {
        CardSlidePanel slidePanel = (CardSlidePanel) rootView
          .findViewById(R.id.image_slide_panel);
        cardSwitchListener = new CardSlidePanel.CardSwitchListener() {
      
         @Override
         public void onShow(int index) {
          Toast.makeText(getContext(), "CardFragment"+"正在顯示=" +index, Toast.LENGTH_SHORT).show();
      
         }
         //type 0=右邊 ,-1=左邊
         @Override
         public void onCardVanish(int index, int type) {
          Toast.makeText(getContext(), "CardFragment"+ "正在消失=" + index + " 消失type=" + type, Toast.LENGTH_SHORT).show();
         }
      
         @Override
         public void onItemClick(View cardView, int index) {
          Toast.makeText(getContext(), "CardFragment"+"卡片點擊=" + index, Toast.LENGTH_SHORT).show();
         }
        };
        slidePanel.setCardSwitchListener(cardSwitchListener);
        prepareDataList();
        slidePanel.fillData(dataList);
       }
       //封裝數(shù)據(jù)
       private void prepareDataList() {
        int num = imagePaths.length;
        //重復(fù)添加數(shù)據(jù)10次(測試數(shù)據(jù)太少)
        for (int j = 0; j < 10; j++) {
         for (int i = 0; i < num; i++) {
          CardDataItem dataItem = new CardDataItem();
          dataItem.imagePath = imagePaths[i];
          dataList.add(dataItem);
         }
        }
       }

      到此主要邏輯代碼就編寫完了

      詳細(xì)說明代碼中已經(jīng)注釋 ,全部代碼請看源碼

      源碼:github源碼

      源碼中的TestCardFragment 為使用模板

      以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。


      網(wǎng)站欄目:Android實現(xiàn)3D層疊式卡片圖片展示
      轉(zhuǎn)載源于:http://www.ef60e0e.cn/article/pigicj.html
      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区
      1. <ul id="0c1fb"></ul>

        <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
        <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

        南阳市| 合水县| 南康市| 宜丰县| 松江区| 奇台县| 高安市| 三亚市| 林芝县| 溧水县| 武清区| 常山县| 大庆市| 富阳市| 固安县| 南和县| 丰顺县| 辽中县| 康保县| 保靖县| 塘沽区| 全椒县| 安阳县| 抚松县| 义乌市| 武夷山市| 鹤壁市| 铜鼓县| 鄂温| 油尖旺区| 饶河县| 阳新县| 资兴市| 菏泽市| 洛浦县| 海阳市| 毕节市| 肃宁县| 罗山县| 舒兰市| 大安市|