1. 程式人生 > >自定義HorizontalScrollView實現左右滑動介面

自定義HorizontalScrollView實現左右滑動介面

public class TimeLimitPurchaseScrollView extends HorizontalScrollView implements
      OnClickListener
{

   /**
    * 圖片滾動時的回撥介面
    *
    * @author zhy
    *
    */
   public interface CurrentImageChangeListener
   {
      void onCurrentImgChanged(int position, View viewIndicator);
   }

   /**
    * 條目點選時的回撥
    *
    * @author zhy
    *
    */
   public interface OnItemClickListener
   {
      void onClick(View view, int pos);
   }

   private CurrentImageChangeListener mListener;

   private OnItemClickListener mOnClickListener;

   private static final String TAG = "MyHorizontalScrollView";

   /**
    * HorizontalListView中的LinearLayout
    */
   private LinearLayout mContainer;

   /**
    * 子元素的寬度
    */
   private int mChildWidth;
   /**
    * 子元素的高度
    */
   private int mChildHeight;
   /**
    * 當前最後一張圖片的index
    */
   private int mCurrentIndex;
   /**
    * 當前第一張圖片的下標
    */
   private int mFristIndex;
   /**
    * 當前第一個View
    */
   private View mFirstView;
   /**
    * 資料介面卡
    */
   private TimeLimitPurchaseAdapter mAdapter;
   /**
    * 每螢幕最多顯示的個數
    */
   private int mCountOneScreen;
   /**
    * 螢幕的寬度
    */
   private int mScreenWitdh;


   /**
    * 儲存View與位置的鍵值對
    */
   private Map<View, Integer> mViewPos = new HashMap<View, Integer>();

   public TimeLimitPurchaseScrollView(Context context, AttributeSet attrs)
   {
      super(context, attrs);
      // 獲得螢幕寬度
      WindowManager wm = (WindowManager) context
            .getSystemService(Context.WINDOW_SERVICE);
      DisplayMetrics outMetrics = new DisplayMetrics();
      wm.getDefaultDisplay().getMetrics(outMetrics);
      mScreenWitdh = outMetrics.widthPixels;
   }

   @Override
   protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
   {
      super.onMeasure(widthMeasureSpec, heightMeasureSpec);
      mContainer = (LinearLayout) getChildAt(0);
   }

   /**
    * 載入下一張圖片
    */
   protected void loadNextImg()
   {
      // 陣列邊界值計算
      if (mCurrentIndex == mAdapter.getCount() - 1)
      {
         return;
      }
      //移除第一張圖片,且將水平滾動位置置0
      scrollTo(0, 0);
      mViewPos.remove(mContainer.getChildAt(0));
      mContainer.removeViewAt(0);
      
      //獲取下一張圖片,並且設定onclick事件,且加入容器中
      View view = mAdapter.getView(++mCurrentIndex, null, mContainer);
      view.setOnClickListener(this);
      mContainer.addView(view);
      mViewPos.put(view, mCurrentIndex);
      
      //當前第一張圖片小標
      mFristIndex++;
      //如果設定了滾動監聽則觸發
      if (mListener != null)
      {
         notifyCurrentImgChanged();
      }

   }
   /**
    * 載入前一張圖片
    */
   protected void loadPreImg()
   {
      //如果當前已經是第一張,則返回
      if (mFristIndex == 0)
         return;
      //獲得當前應該顯示為第一張圖片的下標
      int index = mCurrentIndex - mCountOneScreen;
      if (index >= 0)
      {
//       mContainer = (LinearLayout) getChildAt(0);
         //移除最後一張
         int oldViewPos = mContainer.getChildCount() - 1;
         mViewPos.remove(mContainer.getChildAt(oldViewPos));
         mContainer.removeViewAt(oldViewPos);
         
         //將此View放入第一個位置
         View view = mAdapter.getView(index, null, mContainer);
         mViewPos.put(view, index);
         mContainer.addView(view, 0);
         view.setOnClickListener(this);
         //水平滾動位置向左移動view的寬度個畫素
         scrollTo(mChildWidth, 0);
         //當前位置--,當前第一個顯示的下標--
         mCurrentIndex--;
         mFristIndex--;
         //回撥
         if (mListener != null)
         {
            notifyCurrentImgChanged();

         }
      }
   }

   /**
    * 滑動時的回撥
    */
   public void notifyCurrentImgChanged()
   {
      //先清除所有的背景色,點選時會設定為藍色
      for (int i = 0; i < mContainer.getChildCount(); i++)
      {
         mContainer.getChildAt(i).setBackgroundColor(Color.WHITE);
      }
      
      mListener.onCurrentImgChanged(mFristIndex, mContainer.getChildAt(0));

   }

   /**
    * 初始化資料,設定資料介面卡
    * 
    * @param mAdapter
    */
   public void initDatas(TimeLimitPurchaseAdapter mAdapter)
   {
      this.mAdapter = mAdapter;
      mContainer = (LinearLayout) getChildAt(0);
      // 獲得介面卡中第一個View
      final View view = mAdapter.getView(0, null, mContainer);
      mContainer.addView(view);

      // 強制計算當前View的寬和高
      if (mChildWidth == 0 && mChildHeight == 0)
      {
         int w = MeasureSpec.makeMeasureSpec(0,
               MeasureSpec.UNSPECIFIED);
         int h = MeasureSpec.makeMeasureSpec(0,
               MeasureSpec.UNSPECIFIED);
         view.measure(w, h);
         mChildHeight = view.getMeasuredHeight();
         mChildWidth = view.getMeasuredWidth();
         Log.e(TAG, view.getMeasuredWidth() + "," + view.getMeasuredHeight());
         mChildHeight = view.getMeasuredHeight();
         // 計算每次載入多少個View
         mCountOneScreen = (mScreenWitdh / mChildWidth == 0)?mScreenWitdh / mChildWidth+1:mScreenWitdh / mChildWidth+2;

         Log.e(TAG, "mCountOneScreen = " + mCountOneScreen
               + " ,mChildWidth = " + mChildWidth);
         

      }
      //初始化第一螢幕的元素
      initFirstScreenChildren(mCountOneScreen);
   }

   /**
    * 載入第一屏的View
    * 
    * @param mCountOneScreen
    */
   public void initFirstScreenChildren(int mCountOneScreen)
   {
      mContainer = (LinearLayout) getChildAt(0);
      mContainer.removeAllViews();
      mViewPos.clear();

      for (int i = 0; i < mCountOneScreen; i++)
      {
         View view = mAdapter.getView(i, null, mContainer);
         view.setOnClickListener(this);
         mContainer.addView(view);
         mViewPos.put(view, i);
         mCurrentIndex = i;
      }

      if (mListener != null)
      {
         notifyCurrentImgChanged();
      }

   }

   @Override
   public boolean onTouchEvent(MotionEvent ev)
   {
      switch (ev.getAction())
      {
      case MotionEvent.ACTION_MOVE:
//       Log.e(TAG, getScrollX() + "");

         int scrollX = getScrollX();
         // 如果當前scrollX為view的寬度,載入下一張,移除第一張
         if (scrollX >= mChildWidth)
         {
            loadNextImg();
         }
         // 如果當前scrollX = 0, 往前設定一張,移除最後一張
         if (scrollX == 0)
         {
            loadPreImg();
         }
         break;
      }
      return super.onTouchEvent(ev);
   }

   @Override
   public void onClick(View v)
   {
      if (mOnClickListener != null)
      {
         for (int i = 0; i < mContainer.getChildCount(); i++)
         {
            mContainer.getChildAt(i).setBackgroundColor(Color.WHITE);
         }
         mOnClickListener.onClick(v, mViewPos.get(v));
      }
   }

   public void setOnItemClickListener(OnItemClickListener mOnClickListener)
   {
      this.mOnClickListener = mOnClickListener;
   }

   public void setCurrentImageChangeListener(
         CurrentImageChangeListener mListener)
   {
      this.mListener = mListener;
   }

}
//佈局顯示
<com.emzk.app.view.TimeLimitPurchaseScrollView
    android:id="@+id/id_timeLimitPurchaseScrollView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@android:color/white"
    android:scrollbars="none" >

    <LinearLayout
        android:id="@+id/id_gallery"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >
    </LinearLayout>
</com.emzk.app.view.TimeLimitPurchaseScrollView>
 mStormAdapter = new TimeLimitPurchaseAdapter(getActivity(),mStormListData);
        timeLimitPurchaseScrollView.initDatas(mStormAdapter);
        timeLimitPurchaseScrollView.setOnItemClickListener(new TimeLimitPurchaseScrollView.OnItemClickListener() {
            @Override
            public void onClick(View view, int pos) {
                Intent intent=new Intent(getActivity(),CommodityDetailsPageActivity.class);
//                intent.putExtra("orderId", list.get(position).getOrderId());
                startActivity(intent);
            }
        });
        mStormAdapter.notifyDataSetChanged();
public class TimeLimitPurchaseAdapter extends BaseAdapter {

    Context context;
    List<TimeLimitPurchase> listData;

    public TimeLimitPurchaseAdapter(Context context,
                                    List<TimeLimitPurchase> listData) {
        this.context = context;
        this.listData = listData;
    }

    @Override
    public int getCount() {
        return listData.size();
    }

    @Override
    public Object getItem(int position) {
        return listData.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder;
        final int pos = position;
        if (convertView == null) {
            LayoutInflater inflater = LayoutInflater.from(context);
            convertView = inflater.inflate(R.layout.time_limit_purchase_item, parent, false);
            viewHolder = new ViewHolder();
//                viewHolder.imageView = (ImageView) convertView
//                        .findViewById(R.id.index_gallery_item_image);
            viewHolder.tv_title = (TextView) convertView.findViewById(R.id.tv_title);
            viewHolder.tv_price = (TextView) convertView.findViewById(R.id.tv_price);
            viewHolder.tv_bonus = (TextView) convertView.findViewById(R.id.tv_bonus);
            viewHolder.tv_count_down = (TextView) convertView.findViewById(R.id.tv_count_down);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
            resetViewHolder(viewHolder);
        }

//            ImageLoader.getInstance().displayImage(listData.get(pos).getPigUrl(), viewHolder.imageView);
        viewHolder.tv_title.setText(listData.get(pos).getTitle());
        viewHolder.tv_price.setText("¥" + listData.get(pos).getPrice());
        viewHolder.tv_bonus.setText(listData.get(pos).getBonus() + "元");
        viewHolder.tv_count_down.setText(listData.get(pos).getCount_down());

        return convertView;
    }

    class ViewHolder {
        //            ImageView imageView;
        TextView tv_title;
        TextView tv_price;
        TextView tv_bonus;
        TextView tv_count_down;
    }

    protected void resetViewHolder(ViewHolder viewHolder) {
//            viewHolder.imageView.setImageBitmap(null);
        viewHolder.tv_title.setText("");
        viewHolder.tv_price.setText("");
        viewHolder.tv_bonus.setText("");
    }
}

time_limit_purchase_item佈局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:layout_height="match_parent">
     <LinearLayout
         android:layout_width="300dp"
         android:layout_height="130dp"
         android:layout_marginLeft="5dp"
         android:background="@drawable/circle_rectangle"
         android:orientation="horizontal">
         <LinearLayout
             android:layout_width="0dp"
             android:layout_weight="3"
             android:orientation="vertical"
             android:layout_height="match_parent">
              <TextView
                  android:id="@+id/tv_title"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  android:text="@string/summer_love"
                  android:layout_marginLeft="5dp"
                  android:layout_marginTop="10dp"
                  android:textColor="#666666"
                  />
             <LinearLayout
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_marginTop="5dp"
                 android:orientation="horizontal">
             <TextView
                 android:id="@+id/tv_price"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_marginLeft="5dp"
                 android:textColor="#383838"
                 android:textSize="16sp"
                 android:text="99.00"/>
              <RelativeLayout
                  android:layout_width="wrap_content"
                  android:layout_marginLeft="10dp"
                  android:layout_height="wrap_content">

                   <Button
                       android:id="@+id/tv_bonus"
                       android:layout_width="80dp"
                       android:layout_height="18dp"
                       android:textColor="#E83033"
                       android:paddingLeft="10dp"
                       android:background="@drawable/bonus_oval_background"
                       android:text="800.5元"
                       />
                  <Button
                      android:layout_width="18dp"
                      android:layout_height="18dp"
                      android:textColor="@color/white"
                      android:gravity="center"
                      android:background="@drawable/bonus_round_background"
                      android:text="@string/bonus"/>
              </RelativeLayout>
             </LinearLayout>
             <View
                 android:layout_width="match_parent"
                 android:background="#F2F2F2"
                 android:layout_marginTop="10dp"
                 android:layout_height="1dp"/>
             <TextView
                 android:id="@+id/tv_count_down"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_marginTop="10dp"
                 android:layout_marginLeft="5dp"
                 android:textColor="#999999"
                 android:text="剩 3 天 10 時 15 分 43 秒"
                 />
         </LinearLayout>
         <ImageView
             android:layout_width="0dp"
             android:layout_weight="2"
             android:layout_height="match_parent"
             android:layout_margin="5dp"
             android:src="@mipmap/leishi"/>
     </LinearLayout>
</LinearLayout>

相關推薦

定義HorizontalScrollView實現左右滑動介面

public class TimeLimitPurchaseScrollView extends HorizontalScrollView implements OnClickListener { /** * 圖片滾動時的回撥介面 *

UC瀏覽器主介面滑動摺疊效果 使用定義behavior實現 難度五顆星*****

RcycleView上的HeadScrollBehavior 思路: 1。讓recycleview居於頭部的下方 ---方案:重寫layoutDependsOn  讓當前recycleview去依賴頭部檢視重寫onDependentViewChanged 獲取到依賴的頭部檢視的高度,給recycleview設

實現為fork/join框架生成定義執行緒的ThreadFactory介面

Java 9併發程式設計指南 目錄 實現為fork/join框架生成自定義執行緒的ThreadFactory介面 準備工作 實現過程 工作原理 擴充套件學習 更多關注 fork/join框架是Java9中最有趣的特性之一,它是E

Mybatis定義註解實現DAO層--實現DAO層介面

  Java新增自定義註解:https://www.cnblogs.com/0xcafedaddy/p/6095187.html 1、自定義一個註解@MybatisRepository用作dao掃描 /** * @author cao * @description 前沿my

android 定義ImageView實現圖片手勢滑動,多點觸控放大縮小效果

首先呢,還是一貫作風,我們先來看看眾多應用中的示例:(這種效果是很常見的,可以說應用的必須品.)                             搜狐客戶端                                    百度新聞客戶端          

Android 定義 HorizontalScrollView 打造再多圖片(控制元件)也不怕 OOM 的橫向滑動效果

自從Gallery被谷歌廢棄以後,Google推薦使用ViewPager和HorizontalScrollView來實現Gallery的效果。的確HorizontalScrollView可以實現Gallery的效果,但是HorizontalScrollView存在一個很大的問

定義ViewGroup實現多個單頁面上下滑動效果

閱讀過自定義ViewGroup實現仿淘寶的商品詳情頁的童鞋,應該都瞭解了ViewGroup中onMeasure、onLayout、onTouchEvent等相關方法的使用。在介紹仿淘寶商品詳情頁時,我們提到過現在網上很多實現方法是使用ScrollView巢狀兩個

android 定義ImageView實現圖片手勢滑動 多點觸控放大縮小效果

                轉自:http://blog.csdn.net/jj120522/article/details/8467810首先呢,還是一貫作風,我們先來看看眾多應用中的示例:(這種效果是很常見的,可以說應用的必須品.)                           搜狐客戶端  

iOS 使用純程式碼定義UITableViewCell實現一個簡單的微博介面佈局

一、實現效果 二、使用純程式碼自定義一個UITableViewCell的步驟 1.新建一個繼承自UITableViewCell的類 2.重寫initWithStyle:reuseIdentifier:方法 新增所有需要顯示的子控制元件(不需要設定子控制元件的資料和fram

springboot+redis+Interceptor+定義annotation實現介面自動冪等

前言: 在實際的開發專案中,一個對外暴露的介面往往會面臨很多次請求,我們來解釋一下冪等的概念:任意多次執行所產生的影響均與一次執行的影響相同。按照這個含義,最終的含義就是 對資料庫的影響只能是一次性的,不能重複處理。如何保證其冪等性,通常有以下手段:       &n

Android -- 定義view實現keep歡迎頁倒計時效果

super onfinish -m use new getc awt ttr alt 1,最近打開keep的app的時候,發現它的歡迎頁面的倒計時效果還不錯,所以打算自己來寫寫,然後就有了這篇文章。 2,還是老規矩,先看一下我們今天實現的效果   相較於我們常見的倒計時

Android定義View——實現水波紋效果類似剩余流量球

string 三個點 pre ber block span 初始化 move 理解 最近突然手癢就想搞個貝塞爾曲線做個水波紋效果玩玩,終於功夫不負有心人最後實現了想要的效果,一起來看下吧: 效果圖鎮樓 一:先一步一步來分解一下實現的過程 需要繪制一個正弦曲線(sin

Android定義processor實現bindView功能

lis dds 定義 java代碼 cli 註冊 文章 type() mage 一、簡介 在現階段的Android開發中,註解越來越流行起來,比如ButterKnife,Retrofit,Dragger,EventBus等等都選擇使用註解來配置。按照處理時期,註解又分為兩

定義toast實現

web javascript html5 toast ys_toast.css.ys-toast{ position:fixed; left:0; right:0; top:0; bottom:0; z-index: 999999; } .ys-toast>em{ pos

SpringVC 攔截器+定義註解 實現權限攔截

json.js 加載 bean media tar attr esp 權限 encoding 1.springmvc配置文件中配置 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://w

定義ScrollView 實現上拉下拉的回彈效果--並且子控件中有Viewpager的情況

是否 AS abs pri tar utils lda animation ted onInterceptTouchEvent就是對子控件中Viewpager的處理:左右滑動應該讓viewpager消費 1 public class MyScrollView ext

[python]RobotFramework定義實現UI自動化

bubuko output source 自動 封裝 9.png 全局變量 詳細 變量 1.安裝教程 環境搭建不多說,網上資料一大堆,可參考https://www.cnblogs.com/puresoul/p/3854963.html,寫的比較詳細,值得推薦。目前pyt

NPOI+反射+定義特性實現上傳excel轉List及驗證

type set custom pre script private property xssf don 1.自定義特性 [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited

Android bc信用盤搭建定義behavior 實現上滑 隱藏底部view

退出 Y軸 log rect app sum string dsl oss 布局 <android.support.design.widget.CoordinatorLayout android:layout_width="match_parent"

13、定義Analyzer實現字長過濾

import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.Tokenizer; import org.a