滑块闹钟界面

  先上效果图:

 

  标有on/off的两个滑块是仿照我的“可拖动的按钮”做的自定义View:

  

public class CustomDragView extends ImageButton{

     private int rightBoundary = 10000;                   //向右滑动边界
     private int leftBoundary = 0;                        //向左滑动边界
     private int screenWidth;                             //屏幕宽度
     private int CurrentX;                                //触摸位置X坐标
     private int flag;                                    //判断是否拖动
     private int mid;                                     //滑块中心位置
     private Paint paint = new Paint();
     private boolean isInit = true;
     
     Resources res = getResources();
     //getDisplayMetrics()返回当前展示的metrics.
     //metrics中有density、widthPixels、heighPixelst、scaledDensity、xdpi、ydpi六个属性
     //density英文含义为密度,表示展示的逻辑密度,它是Dip(Density Independent Pixel设备独立像素,也就是常用的dp)的一个比例因子
     //在一个大约160dpi(dot per inch)的屏幕上,一个DIP就是一个像素,这是系统屏显的基准
     //举例:在160dpi的屏幕上density的值为1,在120dpi的屏幕上density的值为0.75
     DisplayMetrics metrics = res.getDisplayMetrics();
     private final int offset = (int) (16.5 * metrics.density);
     private final int textSize = (int) (14 * metrics.density);
     
    public CustomDragView(Context context, int leftBoundary, int rightBoundary) {        
        super(context);
        this.rightBoundary = rightBoundary;
        this.leftBoundary = leftBoundary;
    }
    
    //如果要在XML布局文件中使用该自定义组建,则必须定义该构造方法
    public CustomDragView(Context context, AttributeSet attrs) {
        super(context, attrs, 0);
    }

    //重写onTouchEvent()方法,控制组建随拖动改变位置(只改变X坐标)
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        
        super.onTouchEvent(event);
           int ea=event.getAction();  
           switch(ea)
           {   
           case MotionEvent.ACTION_DOWN:
               CurrentX = (int) event.getRawX();                          //getRawX(),getRawY()获取的是相对于屏幕的坐标值
               flag=0;                                                    //它们是MotionEvent的方法
               break;   

           case MotionEvent.ACTION_MOVE:

               int dx =(int)event.getRawX() - CurrentX;                 //getLeft(),getTop(),getRight(),getBottom()获取
               int left = this.getLeft() + dx;                          //的是组建左、上、右、下边界相对于父布局的坐标值
               int top = this.getTop();                                    //它们是View的方法
               int right = this.getRight() + dx;  
               int bottom = this.getBottom();
               mid = (left + right)/2;
               
               if(mid < leftBoundary){   
                   mid = leftBoundary;   
                   right = mid + this.getWidth() / 2;                    //getWidth(),getHeight()获取的是组建的宽、高,它们是View的方法
                   left = right - this.getWidth();
               }   

               if(mid > rightBoundary){   
                   mid = rightBoundary;   
                   left = mid - this.getWidth() / 2;
                   right = left + this.getWidth();
               } 
               this.layout(left, top, right, bottom); 

               CurrentX = (int) event.getRawX();
               flag=1;
               postInvalidate();
               break;   
           case MotionEvent.ACTION_UP:
               if(flag==0) {
                   return false;
               } else {
                   return true;
               }
           }   
           return true;    
       }
    
    @SuppressLint("NewApi")
    @Override
    protected void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
        super.onDraw(canvas);
        paint.setARGB(255, 255, 255, 255);
        paint.setAntiAlias(true);
        //paint.setTextAlign()设置paint绘制文字的对齐方式:
        //Paint.Align.CENTER表示居中对齐
        //Paint.Align.LEFT、Paint.Align.RIGHT分别表示左对齐、右对齐
        paint.setTextAlign(Paint.Align.CENTER);
        paint.setTextSize(textSize);
        
        if(isInit) {
            mid = (getLeft()+getRight()) / 2;
            rightBoundary = screenWidth;
            leftBoundary = 0;
            isInit = false;
        }
        
        //下面的方法控制控件绘制text的方法:通常情况下,控件将时间绘制在中间
        //当控件左边缘滑动到屏幕左边之后,文字偏向右边显示,反之,偏向左边显示
        if(mid >= (getRight() - getLeft())/2 - offset && mid <= screenWidth - (getRight() - getLeft())/2 + offset) {
            //Canvas.drawText(String text, float x, float y, Paint paint)方法中
            //x表示绘制文字的起始位置(左边),y则表示绘制文字的baseline,也就是底部位置,
            //这两个数值都是相对于控件的位置,不是相对于屏幕的位置。
            canvas.drawText(Cast_X_to_time(), (getRight() - getLeft())/2, textSize, paint);
        } else if(mid < (getRight() - getLeft())/2 - offset) {
            canvas.drawText(Cast_X_to_time(), getWidth() - mid - offset, textSize, paint);
        } else if(mid > screenWidth - (getRight() - getLeft())/2 + offset) {
            canvas.drawText(Cast_X_to_time(), screenWidth - mid + offset, textSize, paint);
        }
    }

    public int getflag() {
        return flag;
    }
    
    public void setLeftBoundary(int leftBoundary) {
        this.leftBoundary = leftBoundary;
    }
    
    public void setRightBoundary(int rightBoundary) {
        this.rightBoundary = rightBoundary;
    }
    
    public void setScreenWidth(int screenWidth) {
        this.screenWidth = screenWidth;
    }
    
    public int getLeftBoundary() {
        return leftBoundary;
    }
    
    public int getRightBoundary() {
        return rightBoundary;
    }
    
    public int getXposition() {
        return mid;
    }
    
    public void setLayout(int left){
        this.layout(left, this.getTop(), left+this.getWidth(), this.getBottom());
        mid = left + this.getWidth() / 2;
        invalidate();
    }/**
     * @author sofa
     * 如果把屏幕横坐标换轴当作时间轴,该方法把屏幕横坐标换算为时间
     * @return
     */
    private String Cast_X_to_time() {
        float temp = (float)mid * 1440 / screenWidth ;
        int hour = (int) (temp / 60);
        int min = (int) (temp % 60);
        if(min >= 10)
            return ""+hour+":"+min;
        else {
            return ""+hour+":0"+min;
        }
    }
}

 

  on/off滑块下面的色块条也是自定义View:

 

public class CustomLengthView extends Button{
    
    private int leftBoundary = 0;
    private int rightBoundary = 0;
    private int mCurrentX;
    private boolean ifAddNewTiming = true; 
    private List<Zone> list = new ArrayList<Zone>();
    private List<Zone> tempList = new ArrayList<Zone>();
    private Paint paint = new Paint();
    private final int lineWidth = 3;
    
    public CustomLengthView(Context context) { 
        super(context);
    }

    public CustomLengthView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    @SuppressLint("ResourceAsColor")
    @Override
    protected void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
//        super.onDraw(canvas);
        paint.setARGB(255, 32, 201, 147);
        //绘制边框
        canvas.drawRect(0, 0, getRight(), lineWidth, paint);
        canvas.drawRect(0, getBottom()-getTop()-lineWidth, getRight(), getBottom() - getTop(), paint);
        //绘制正在随滑块变动的灰色色块
        if(ifAddNewTiming) {
            paint.setARGB(255, 67, 80, 76);
            canvas.drawRect(leftBoundary, lineWidth, rightBoundary, getBottom() - getTop() - lineWidth, paint);
        }
        //绘制待添加的灰色色块
        for(int i = 0; i < tempList.size(); i++) {
            paint.setARGB(255, 67, 80, 76);
            canvas.drawRect(tempList.get(i).startX, lineWidth, tempList.get(i).endX, getBottom() - getTop() - lineWidth, paint);
        }
        //绘制已经添加的绿色色块
        for(int i = 0; i < list.size(); i++) {
            paint.setARGB(255, 32, 201, 147);
            canvas.drawRect(list.get(i).startX, lineWidth, list.get(i).endX, getBottom() - getTop() - lineWidth, paint);
        }
    }
    
    public void setBoundary(int left, int right) {
        leftBoundary = left;
        rightBoundary = right;
        postInvalidate();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // TODO Auto-generated method stub
        int ea=event.getAction();  
        switch (ea) {
        case MotionEvent.ACTION_DOWN:
            mCurrentX = (int) event.getRawX();
            Log.v("ACTION_DOWN","ACTION_DOWN");
            break;
        case MotionEvent.ACTION_MOVE:
            Log.v("ACTION_MOVE","ACTION_MOVE");
            break;
        case MotionEvent.ACTION_UP:
            Log.v("ACTION_UP","ACTION_UP");
            break;
        default:
            break;
        }
        return super.onTouchEvent(event);
        
    }

    public int getTouchedX() {
        return mCurrentX;
    }
    
    public void setNewTimingZone(int startX, int endX) {
        Zone zone = new Zone();
        zone.startX = startX;
        zone.endX = endX;
        list.add(zone);
        postInvalidate();
    }
    
    public void setTempTimingZone(int startX, int endX) {
        Zone zone = new Zone();
        zone.startX = startX;
        zone.endX = endX;
        tempList.add(zone);
        postInvalidate();
    }
    
    public void clearTempTimingZone() {
        tempList.clear();
    }
    
    public void deleteTimingZone(int x) {
        for(int i = 0; i < list.size(); i++) {
            if(list.get(i).startX <= x && list.get(i).endX >=x) {
                list.remove(i);
                postInvalidate();
            }
        }
    }
    
    private class Zone {
        int startX;
        int endX;
    }
    
    public List<Zone> getList() {
        return list;
    }

    public void setList(List<Zone> list) {
        this.list = list;
    }

    public List<Zone> getTempList() {
        return tempList;
    }

    public void setTempList(List<Zone> tempList) {
        this.tempList = tempList;
    }
}

 

  布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="#000"
    android:layout_marginTop="18dp"
    tools:context=".MainActivity" >

    <RelativeLayout 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#1f1f1f"
        >
        
        <Button 
            android:id="@+id/timer_save"
            android:layout_width="53.5dp"
            android:layout_height="21.5dp"
            android:background="#0000"
            android:text="@string/timer_save"
            android:textColor="#fff"
            android:textSize="14dp"
            android:layout_centerVertical="true"
            android:layout_alignParentRight="true"/>
        
        <ImageView 
            android:layout_width="1dp"
            android:layout_height="12dp"
            android:background="#fff"
            android:layout_centerVertical="true"
            android:layout_toLeftOf="@id/timer_save"
            />
        <Button 
            android:id="@+id/timer_add"
            android:layout_width="53.5dp"
            android:layout_height="21.5dp"
            android:background="#0000"
            android:text="@string/timer_add"
            android:textColor="#fff"
            android:textSize="14dp"
            android:layout_centerVertical="true"
            android:layout_toLeftOf="@id/timer_save"
            />"
        
    </RelativeLayout>
    <RelativeLayout 
        android:id="@+id/timer_layout"
        android:layout_width="fill_parent"
        android:layout_height="200dp"
        android:background="#1f1f1f"
        >
        <com.example.test1.CustomDragView
            android:id="@+id/rihgtDragView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/timing_off"
            android:layout_alignParentRight="true"
            android:layout_alignParentBottom="true"
            />
    
        <com.example.test1.CustomDragView
            android:id="@+id/leftDragView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/timing_on"
            android:layout_alignParentBottom="true"
            />
        <View
            android:id="@+id/invisible_view"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:background="#0000"
            />
    </RelativeLayout>
    
    <com.example.test1.CustomLengthView
        android:id="@+id/lengthView"
        android:layout_width="match_parent"
        android:layout_height="30.5dp"
        android:background="#1f1f1f"
        />
    
    <RelativeLayout 
        android:layout_width="fill_parent"
        android:layout_height="25dp"
        >
        
        <ImageView
            android:id="@+id/timer_repeat"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/timing_repeat_default"
            android:layout_centerVertical="true"
            android:layout_alignParentRight="true"
            android:layout_marginRight="35dp"
            />
        
        <TextView 
            android:id="@+id/timer_repeat_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/timer_repeat"
            android:layout_centerVertical="true"
            android:layout_toLeftOf="@id/timer_repeat"
            android:layout_marginRight="11dp"
            />
        
    </RelativeLayout>

    <RelativeLayout 
        android:layout_width="fill_parent"
        android:layout_height="32dp"
        android:background="#1f1f1f"
        >
        <GridView 
            android:id="@+id/timer_gridview"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:gravity="center"
            android:numColumns="7"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            />
    </RelativeLayout>
</LinearLayout>

 

  测试Activity:

 

public class MainActivity extends Activity {

    CustomDragView leftDragView;
    CustomDragView rightDragView;
    CustomLengthView lengthView;
    private final String[] days = new String[] {
            "日","一","二","三","四","五","六",
    };
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //获得屏幕分辨率
        DisplayMetrics dm = getResources().getDisplayMetrics();
        final int screenWidth = dm.widthPixels;
        View view = findViewById(R.id.invisible_view);
        view.setOnTouchListener(new OnTouchListener() {
            
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                // TODO Auto-generated method stub
                return true;
            }
        });
        
        view.setVisibility(View.GONE);
//        view.setVisibility(View.VISIBLE);
        
        leftDragView = (CustomDragView)findViewById(R.id.leftDragView);
        rightDragView = (CustomDragView)findViewById(R.id.rihgtDragView);
        lengthView = (CustomLengthView)findViewById(R.id.lengthView);
        
        leftDragView.setLeftBoundary(leftDragView.getWidth()/2);
        rightDragView.setRightBoundary(screenWidth - rightDragView.getWidth()/2);
        
        leftDragView.setScreenWidth(screenWidth);
        rightDragView.setScreenWidth(screenWidth);
        
        leftDragView.setFocusableInTouchMode(false);
        rightDragView.setFocusableInTouchMode(false);
        
//        lengthView.setBoundary(rightDragView.getLeftBoundary(),leftDragView.getRightBoundary());
        leftDragView.setOnTouchListener(new OnTouchListener() {
            
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                // TODO Auto-generated method stub
                int ea=event.getAction(); 
                switch (ea) {
                case MotionEvent.ACTION_DOWN:
                    leftDragView.setRightBoundary(rightDragView.getLeft() + rightDragView.getWidth() / 2);
                    break;
                case MotionEvent.ACTION_MOVE:
                    rightDragView.setLeftBoundary(leftDragView.getRight() - leftDragView.getWidth() / 2);
                    lengthView.setBoundary(rightDragView.getLeftBoundary(),leftDragView.getRightBoundary());
                    break;
                case MotionEvent.ACTION_UP:
                    rightDragView.setLeftBoundary(leftDragView.getRight() - leftDragView.getWidth() / 2);
                    lengthView.setBoundary(rightDragView.getLeftBoundary(),leftDragView.getRightBoundary());
                    break;
                default:
                    break;
                }
                return false;
            }
        });
        
        rightDragView.setOnTouchListener(new OnTouchListener() {
            
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                // TODO Auto-generated method stub
                 int ea=event.getAction(); 
                    switch (ea) {
                    case MotionEvent.ACTION_DOWN:
                        rightDragView.setLeftBoundary(leftDragView.getRight() - leftDragView.getWidth() / 2);
                        break;
                    case MotionEvent.ACTION_MOVE:
                        leftDragView.setRightBoundary(rightDragView.getLeft() + rightDragView.getWidth() / 2);
                        lengthView.setBoundary(rightDragView.getLeftBoundary(),leftDragView.getRightBoundary());
                        break;
                    case MotionEvent.ACTION_UP:
                        leftDragView.setRightBoundary(rightDragView.getLeft() + rightDragView.getWidth() / 2);
                        lengthView.setBoundary(rightDragView.getLeftBoundary(),leftDragView.getRightBoundary());
                        break;
                    default:
                        break;
                    }
                return false;
            }
        });
        lengthView.setClickable(true);
        lengthView.setOnLongClickListener(new OnLongClickListener() {
            
            @Override
            public boolean onLongClick(View v) {
                // TODO Auto-generated method stub
                lengthView.deleteTimingZone(lengthView.getTouchedX());
                return false;
            }
        });
        
        List<Map<String, Object>> listItems = new ArrayList<Map<String, Object>>();
        for(int i = 0; i < days.length; i++) {
            Map<String, Object> listItem = new HashMap<String, Object>();
            listItem.put("day", days[i]);
            listItems.add(listItem);
        }
        
        SimpleAdapter simpleAdapter = new SimpleAdapter(this
                , listItems, R.layout.smart_socket_new_timer_gridviewitem
                , new String[]{"day"}, new int []{R.id.smart_socket_new_timer_gridviewitem_text});
        GridView gridView = (GridView)findViewById(R.id.smart_socket_new_timer_gridview);
        gridView.setAdapter(simpleAdapter);
        
        lengthView.setNewTimingZone(50, 250);
        lengthView.setTempTimingZone(300, 350);
        lengthView.setNewTimingZone(500, 700);
        leftDragView.postDelayed(new Runnable(){

            @Override
            public void run() {
                // TODO Auto-generated method stub
                leftDragView.setLayout(300);
                leftDragView.invalidate();
            } 
        },300);
//        leftDragView.setLayout(600);
//        rightDragView.setLayout(250);
    }

}

 

posted @ 2014-04-24 14:45  沙发土豆  阅读(336)  评论(0编辑  收藏  举报