[lottery] 01_双色球选号(二)——选中弹出PopWindow自定义图片

Android 4.0

双色球选号(二)——仿淘宝(选中弹出PopWindow自定义图片)

步骤:1、自定义MyGridView继承GridView类
2、实现触摸事件
获取当前位置,是否有效
①按下:
在有效的位置按下,就弹出来showAsDrop(view,..)一个PopWindow,
处理其显示的位置(默认在view的左下角),让其在view的中间
②移动:
在移动的时候,让PopWindow也跟着移动
③松手:
松手的时候,将PopWindow给dismiss()掉,并在松手时,选中当前的item,需要设置一个监听松手时的事件
3、自定义一个OnItemClickListener(),可以在按下,并移动的时候,最后松手的时候,将松手前的item给选中
4、PopupWindow显示的位置
技术点:
1、getX()和getRawX()区别:
getX()是表示Widget相对于自身左上角的x坐标,而getRawX()是表示相对于屏幕左上角的x坐标值(注意:这个屏幕左上角是手机屏幕左上角,不管activity是否有titleBar或是否全屏幕),getY(),getRawY()一样的道理
2、PopupWindow
popupWindow.setAnimationStyle(0);// 取消动画
popupWindow.setBackgroundDrawable(null);// 取消背景
popupWindow.update(anchor, xoff, yoff, -1, -1);// 如果已经显示了,不能再使用showAsDropDown()了,而要用update()
// 宽度和高度:仅仅更新pop的位置不需要修改宽度和高度,设置为-1,忽略这两个参数  
3、GridView
View anchor = this.getChildAt(itemId);//根据item的位置获取View
4、 自定义控件
①利用系统提供的控件进行组拼
②继承系统现有的控件,加强版
③View或ViewGroup
布局:
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:orientation="vertical" >
    <TextView
        android:id="@+id/tv_pretextView_zl"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/id_ball_tip_red"
        android:gravity="center"
        android:textColor="@color/black"
        android:textSize="20.0dp"
        android:textStyle="bold" />
</LinearLayout>
核心代码:
package cn.zengfansheng.lottery.view.custom;
import java.text.DecimalFormat;
import android.content.Context;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.widget.GridView;
import android.widget.PopupWindow;
import android.widget.TextView;
import cn.zengfansheng.lottery.R;
import cn.zengfansheng.lottery.util.DensityUtil;
import cn.zengfansheng.lottery.util.LogUtil;
/**
 * 自定义的GridView
 * 
 * @author hacket
 */
public class MyGridView extends GridView {
    // 主要工作:控制popwindow的显示
    private static final String TAG = "MyGridView";
    public MyGridView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }
    public MyGridView(Context context) {
        super(context);
        init();
    }
    
    // note*********************1、初始化工作*********************
    private PopupWindow popupWindow;
    private TextView tvBall;
    public void init() {
        View view = View.inflate(getContext(), R.layout.zl_gridview_item_popnull);
        tvBall = (TextView) view.findViewById(R.id.tv_pretextView_zl);
        tvBall.setGravity(Gravity.CENTER);
        // 创建一个popupWindow
        popupWindow = new PopupWindow();
        
        // 设置pop的宽度高度
        popupWindow.setHeight(DensityUtil.dip2px(getContext(), 50));
        popupWindow.setWidth(DensityUtil.dip2px(getContext(), 50));
        popupWindow.setAnimationStyle(0);// 取消动画
        popupWindow.setBackgroundDrawable(null);// 取消背景
        // 设置pop显示的view
        popupWindow.setContentView(view);
    }
    
    // note*********************2、触摸事件*********************
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // 1、获取触摸坐标(离屏幕左上角)
        int x = (int) event.getX();// 获取的是离屏幕的左上角的x轴坐标
        int y = (int) event.getY();
        // 2、将该坐标转换成为GridView中对应的item
        int itemId = this.pointToPosition(x, y);// 返回的是该点坐标在gridView中的item,INVALID_POSITION(-1)表示该位置没有item
        if (itemId == GridView.INVALID_POSITION) {// 无效的位置,没有对应的item
            if (popupWindow.isShowing()) {
                popupWindow.dismiss();
            }
            return false;
        }
        // 3、获取GridView中itemId位置对应的View
        View anchor = this.getChildAt(itemId);
        // 4、设置popupWindow偏移的位置
        int xoff = -(popupWindow.getWidth() - anchor.getWidth()) / 2;
        int yoff = -(popupWindow.getHeight() + anchor.getWidth());
        // 5、格式化popupWindow显示文本的格式
        DecimalFormat df = new DecimalFormat("00");
        String position = df.format(itemId + 1);
        tvBall.setText(position);
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            popupWindow.dismiss();
            // 当按下的时候,显示PopupWindow
            showPopupWindow(anchor, xoff, yoff);
            break;
        case MotionEvent.ACTION_MOVE:
            // 在选中某一个item时,拖动时,ancher也可以拖动
            showPopupWindow(anchor, xoff, yoff);
            break;
        case MotionEvent.ACTION_UP:
            if (popupWindow.isShowing()) {
                popupWindow.dismiss();
            }
            // 在抬起手的时候,将选中的item,更新为松手下的item
            if (onItemUPListener != null) {
                onItemUPListener.itemActionUp(anchor, itemId);
            }
            break;
        default:
            if (popupWindow.isShowing()) {
                LogUtil.i(TAG"default~");
                popupWindow.dismiss();
            }
            break;
        }
        return super.onTouchEvent(event);
    }
    // note*********************3、PopupWindow的显示*********************
    private void showPopupWindow(View anchor, int xoff, int yoff) {
        // 两个问题
        // 1、pop显示在那个View anchor
        // 2、pop显示的偏移量(默认在anchor的左下角)
        if (popupWindow.isShowing()) {// 如果pop已经显示了
            // popupWindow.showAsDropDown(anchor, xoffyoff);//
            popupWindow.update(anchor, xoff, yoff, -1, -1);// 如果已经显示了,不能再使用showAsDropDown()了,而要用update()
            // 宽度和高度:仅仅更新pop的位置不需要修改宽度和高度,设置为-1,忽略这两个参数
        } else {
            popupWindow.showAsDropDown(anchor, xoff, yoff);
        }
    }
    
    // note*********************4、接口和监听*********************
    private OnItemUPListener onItemUPListener;
    
    /**
     * 松手时监听器接口
     * 
     * @author hacket
     */
    public interface OnItemUPListener{
        /**
         * 松手时调用的方法
         * 
         * @param anchor
         *            松手时坐标对应的View
         * @param position
         *            松手时对应的item位置
         */
        public abstract void itemActionUp(View anchor,int position);
        
    }
    
    /**
     * 设置松手时的监听事件
     * 
     * @param onItemUPListener
     */
    public void setOnItemUpListener(OnItemUPListener onItemUPListener) {
        this.onItemUPListener = onItemUPListener;
    }
}
结果: