Android自定义View仿IOS圆盘时间选择器
通过自定义view实现仿iOS实现滑动两端的点选择时间的效果
效果图
自定义的view代码
代码如下 | 复制代码 |
publicclassRing_Slide2extendsView { privatestaticfinaldoubleRADIAN =180/ Math.PI; privateintmax_progress;// 设置最大进度 privateintcur_progress;//设置锚点1当前进度 privateintcur_progress2;//设置锚点2进度 privateintbottom_color;//设置底色 privateintcircle_color;//设置圆的颜色(锚点) privateintslide_color;//设置滑动过的颜色 privatefloatring_width;//圆环的宽度 privatedoublecur_Angle;//当前锚点1旋转角度 privatedoublecur_Angle2;//当前锚点2的旋转角度 privatefloatring_Radius;//圆环的半径 privatefinalint[] arrColorCircle =newint[]{0xFFFFde37,0xFFFFa400}; privateintmain_width;//圆的宽度 privatefloatmWheelCurX, mWheelCurY;//圆的位置 privatefloatmWheelCurX2, mWheelCurY2;//圆2的位置 privatePaint circle_Paint;//圆环的画笔 privatePaint select_Paint;//选中的画笔 privatePaint dot1;//圆点1 privatePaint dot2;//圆点2 privateContext context; privateOnSeekBarChangeListener changeListener,changeListener2; publicRing_Slide2(Context context) { this(context,null); } publicRing_Slide2(Context context, AttributeSet attrs) { this(context, attrs,0); } publicRing_Slide2(Context context, AttributeSet attrs,intdefStyleAttr) { super(context, attrs, defStyleAttr); this.context=context; initAttrs(attrs,defStyleAttr); initPadding(); //初始化画笔 initPaints(); } //初始化属性 privatevoidinitAttrs(AttributeSet attrs,intdefStyle){ TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.Cricle_slide, defStyle,0); max_progress=typedArray.getInt(R.styleable.Cricle_slide_max_progress,720); cur_progress=typedArray.getInt(R.styleable.Cricle_slide_cur_progress,420); cur_progress2=typedArray.getInt(R.styleable.Cricle_slide_cur_progress2,540); if(cur_progress > max_progress) cur_progress = max_progress; if(cur_progress2 > max_progress) cur_progress2 = max_progress; Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.select_sun_bg2); main_width= bitmap.getWidth(); ring_width=typedArray.getFloat(R.styleable.Cricle_slide_Ring_Width,main_width); bottom_color=typedArray.getColor(R.styleable.Cricle_slide_bottom_color,getColor(R.color.select_main_bg_color)); circle_color=typedArray.getColor(R.styleable.Cricle_slide_circle_color,getColor(R.color.duration)); slide_color=typedArray.getColor(R.styleable.Cricle_slide_slide_color,getColor(R.color.time)); typedArray.recycle(); } //初始化边距 privatevoidinitPadding(){ intpaddingLeft = getPaddingLeft(); intpaddingTop = getPaddingTop(); intpaddingRight = getPaddingRight(); intpaddingBottom = getPaddingBottom(); intpaddingStart =0, paddingEnd =0; if(Build.VERSION.SDK_INT >=17) { paddingStart = getPaddingStart(); paddingEnd = getPaddingEnd(); } intmaxPadding = Math.max(paddingLeft, Math.max(paddingTop, Math.max(paddingRight, Math.max(paddingBottom, Math.max(paddingStart, paddingEnd))))); setPadding(maxPadding, maxPadding, maxPadding, maxPadding); } privatevoidinitPaints(){ /* 圆环的画笔 */ circle_Paint=new Paint(Paint.ANTI_ALIAS_FLAG); circle_Paint.setAntiAlias(true); circle_Paint.setColor(bottom_color); circle_Paint.setStyle(Paint.Style.STROKE); circle_Paint.setStrokeWidth(ring_width); /* 选中区域的画笔 */ select_Paint=new Paint(Paint.ANTI_ALIAS_FLAG); select_Paint.setShader(new SweepGradient(0, 0, arrColorCircle, null)); /*select_Paint.setColor(circle_color);*/ select_Paint.setAntiAlias(true); select_Paint.setStyle(Paint.Style.STROKE); select_Paint.setStrokeWidth(ring_width); // 画锚点 dot1 = new Paint(Paint.ANTI_ALIAS_FLAG); dot1.setColor(circle_color); dot1.setAntiAlias(true); dot1.setStyle(Paint.Style.FILL); // 画锚点2 dot2 = new Paint(Paint.ANTI_ALIAS_FLAG); dot2.setColor(slide_color); dot2.setAntiAlias(true); dot2.setStyle(Paint.Style.FILL); } //获取宽度 private float getDimen(int dimenId) { return getResources().getDimension(dimenId); } //获取颜色 @TargetApi(Build.VERSION_CODES.M) private int getColor(int colorId) { final int version = Build.VERSION.SDK_INT; if (version >= 23) { return getContext().getColor(colorId); } else { return ContextCompat.getColor(getContext(), colorId); } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.setalarm_colock_bg); int height = bitmap.getHeight()+main_width*2; int width = bitmap.getWidth()+main_width*2; int min = Math.min(height, width); setMeasuredDimension(min,min); initposition(); } private void initposition(){ //转换为360度 cur_Angle=(double) cur_progress / max_progress*360.0; cur_Angle2=(double)cur_progress2 / max_progress*360.0; //计算初始化旋转的角度 double cos = -Math.cos(Math.toRadians(cur_Angle)); double cos2 = -Math.cos(Math.toRadians(cur_Angle2)); //根据旋转的角度来确定位置 MakeCurPosition(cos); MakeCurPosition2(cos2); //确定圆环的半径 ring_Radius=(getMeasuredWidth() - getPaddingLeft() - getPaddingRight() - ring_width) / 2; } private void MakeCurPosition(double cos){ //根据旋转的角度来确定圆的位置 //确定x点的坐标 mWheelCurX = calcXLocationInWheel(cur_Angle, cos); //确定y点的坐标 mWheelCurY=calcYLocationInWheel(cos); } private void MakeCurPosition2(double cos2){ //根据旋转的角度来确定圆的位置 //确定x点的坐标 mWheelCurX2 = calcXLocationInWheel(cur_Angle2, cos2); //确定y点的坐标 mWheelCurY2=calcYLocationInWheel(cos2); } //确定x点的坐标 private float calcXLocationInWheel(double angle,double cos){ if (angle < 180) { return (float) (getMeasuredWidth() / 2 + Math.sqrt(1 - cos * cos) * ring_Radius); //Math.sqrt正平分根 9-3 } else { return (float) (getMeasuredWidth() / 2 - Math.sqrt(1 - cos * cos) * ring_Radius); } } //确定y点的坐标 private float calcYLocationInWheel(double cos) { return getMeasuredWidth() / 2 + ring_Radius * (float) cos; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); float left = getPaddingLeft() + ring_width / 2; float top = getPaddingTop() + ring_width / 2; float right = canvas.getWidth() - getPaddingRight() - ring_width / 2; float bottom = canvas.getHeight() - getPaddingBottom() - ring_width / 2; float centerX = (left + right) / 2; float centerY = (top + bottom) / 2; float wheelRadius = (canvas.getWidth() - getPaddingLeft() - getPaddingRight()) / 2 - ring_width / 2; canvas.drawCircle(centerX, centerY, wheelRadius, circle_Paint); //画选中区域 // canvas.drawArc(new RectF(left, top, right, bottom), (float) (Math.PI * RADIAN + Math.acos(cur_Angle) * RADIAN), (float) (Math.abs(cur_Angle-cur_Angle2)), false, select_Paint); Log.i("TAG","第一个的角度="+cur_Angle); Log.i("TAG","第一个的角度2="+cur_Angle2); float begin=0; //圆弧的起点位置 float stop=0; if(cur_Angle>180 && cur_Angle>cur_Angle2 ){ //180 -- 360 begin=(float) (-Math.abs(cur_Angle-360)-90); stop=(float) Math.abs(Math.abs(cur_Angle-360)+cur_Angle2); Log.i("TAG","begin="+begin); Log.i("TAG","stop="+stop); }else if(cur_Angle>cur_Angle2){ begin=(float) cur_Angle-90; stop=(float)(360-(cur_Angle-cur_Angle2)); }else { begin=(float) cur_Angle-90; stop=(float) Math.abs(cur_Angle-cur_Angle2); } canvas.drawArc(new RectF(left, top, right, bottom), begin,stop, false, select_Paint); //画锚点 画圆 canvas.drawCircle(mWheelCurX, mWheelCurY, ring_width/2, dot1); //画锚点 画圆 canvas.drawCircle(mWheelCurX2, mWheelCurY2, ring_width/2, dot2); Log.i("TAG","锚点1Y"+mWheelCurY+"锚点1X"+mWheelCurX); Log.i("TAG","锚点2Y"+mWheelCurY2+"锚点1X"+mWheelCurX2); } @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); int flag=0; //判断是否触控到两个点中的其中某个点 if(isMovedot2(x,y)){ flag=2; }else if(isMovedot1(x,y)){ flag=1; } /* if(isMovedot1(x,y)){ flag=1; }else if(isMovedot2(x,y)){ flag=2; }*/ if(event.getAction()==MotionEvent.ACTION_MOVE || isMovedot1(x,y) ==true|| isMovedot2(x,y)==true){ Log.i("TAG","进入X="+x+"进入Y="+y); //通过触摸点算出cos角度值 floatcos = calculateCos(x, y); // 通过反三角函数获得角度值 doubleangle;//获取滑动的角度 if(x < getWidth() /2) {// 滑动超过180度 angle = Math.PI * RADIAN + Math.acos(cos) * RADIAN;//通过计算得到滑动的角度值 }else{// 没有超过180度 angle = Math.PI * RADIAN - Math.acos(cos) * RADIAN;//PI 周长比直径 返回弧角度的余弦值 } if(flag==1){ cur_Angle=angle; cur_progress=getSelectedValue(cur_Angle); MakeCurPosition(cos); if(changeListener !=null) { changeListener.onChanged(this, cur_progress); } }elseif(flag==2){ cur_Angle2=angle; cur_progress2=getSelectedValue(cur_Angle2); MakeCurPosition2(cos); if(changeListener2 !=null) { changeListener2.onChanged(this, cur_progress2); } } invalidate(); returntrue; }else{ returnsuper.onTouchEvent(event); } } privatebooleanisMovedot1(floatx,floaty){ floatdot1x = Math.abs(mWheelCurX - x); floatdot1y = Math.abs(mWheelCurY - y); if(dot1x<30&& dot1y<30){ returntrue; }else{ returnfalse; } } privatebooleanisMovedot2(floatx,floaty){ floatdot1x = Math.abs(mWheelCurX2 - x); floatdot1y = Math.abs(mWheelCurY2 - y); if(dot1x<30&& dot1y<30){ returntrue; }else{ returnfalse; } } //拿到切斜角的cos值 privatefloatcalculateCos(floatx,floaty){ floatwidth = x - getWidth() /2; floatheight = y - getHeight() /2; floatslope = (float) Math.sqrt(width * width + height * height); returnheight / slope; } privateintgetSelectedValue(doublemCurAngle) {//角度转进度 returnMath.round(max_progress * ((float) mCurAngle /360));//四舍五入 } publicvoidsetOnSeekBarChangeListener(OnSeekBarChangeListener listener) { changeListener = listener; } publicvoidsetOnSeekBarChangeListener2(OnSeekBarChangeListener listener) { changeListener2 = listener; } publicvoidinitRadian(intpro1,intpro2){ this.cur_progress=pro1; this.cur_progress2=pro2; invalidate(); } publicinterfaceOnSeekBarChangeListener { voidonChanged(Ring_Slide2 seekbar,intcurValue); } } |
自定义stayle样式,在values下新建sttrs.xml文件
代码如下 | 复制代码 |
//设置最大进度
//设置当前进度
//设置当前进度
//设置底色
//设置圆的颜色
//设置滑动的颜色
//圆环的宽度 (dimension是代表尺寸值)
|
这篇文章主要介绍了Android编程之ActionBar Tabs用法,结合实例形式分析了ActionBar Tabs的功能及Tab切换不同的Fragment的相关实现技巧,需要的朋友可以参考下
这里主要实现用Tab切换不同的Fragment,点击View显示or隐藏ActionBar,把ActionBar 设为透明,使界面更加友好,详细代码见资源里的ActionBarTabs。
ActionBar Tab主要用于Fragment之间的切换,其必须要设置ActionBar.TabListener,详细代码如下
ActionBarActivity.Java:
代码如下 | 复制代码 |
importandroid.app.ActionBar; importandroid.app.Activity; importandroid.app.FragmentTransaction; importandroid.app.ActionBar.Tab; importandroid.os.Bundle; importandroid.os.CountDownTimer; importandroid.view.MotionEvent; importandroid.view.Window; publicclassActionBarActivityextendsActivity { /** Called when the activity is first created. */ @Override publicvoidonCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //使ActionBar变得透明 requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY); setContentView(R.layout.main); finalActionBar actionBar = getActionBar(); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); // remove the activity title to make space for tabs actionBar.setDisplayShowTitleEnabled(false); AFragment aFragment =newAFragment(); actionBar.addTab(actionBar.newTab().setText("Tab-A") .setTabListener(newListenerA(aFragment))); BFragment bFragment =newBFragment(); actionBar.addTab(actionBar.newTab().setText("Tab-B") .setTabListener(newListenerB(bFragment))); } //点击显示or隐藏ActionBar publicbooleanonTouchEvent(MotionEvent event){ ActionBar bar = getActionBar(); switch(event.getAction()){ caseMotionEvent.ACTION_UP: if(bar.isShowing()) bar.hide(); elsebar.show(); break; default: break; } returntrue; } privateclassListenerAimplementsActionBar.TabListener { privateAFragment mFragment; // Called to create an instance of the listener when adding a new tab publicListenerA(AFragment fragment) { mFragment = fragment; } publicvoidonTabSelected(Tab tab, FragmentTransaction ft) { ft.add(R.id.fragment, mFragment,null); } publicvoidonTabUnselected(Tab tab, FragmentTransaction ft) { ft.remove(mFragment); } publicvoidonTabReselected(Tab tab, FragmentTransaction ft) { // do nothing } } } privateclassListenerBimplementsActionBar.TabListener { privateBFragment mFragment; // Called to create an instance of the listener when adding a new tab publicListenerB(BFragment fragment) { mFragment = fragment; } publicvoidonTabSelected(Tab tab, FragmentTransaction ft) { ft.add(R.id.fragment, mFragment,null); } publicvoidonTabUnselected(Tab tab, FragmentTransaction ft) { ft.remove(mFragment); } publicvoidonTabReselected(Tab tab, FragmentTransaction ft) { // do nothing } } } } |
其中涉及到两个Fragment,在前面Fragment的笔记中讲过,这里就不再赘述。类AFragment实现如下,BFragment实现与这类似:
代码如下 | 复制代码 |
publicclassAFragmentextendsFragment { publicView onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { returninflater.inflate(R.layout.alayout, container,false); } } |
小编给大家推荐的这篇文章介绍了 Android编程之交互对话框实例浅析,非常实用,有兴趣的同学快来看看吧!
1. 在Android SDK中,虽然有许多的窗口,有些类似Modeless的窗口、有些类似于前端Force Focus的窗口,但真正具有交互功能的则为AlertDialog对话窗口。
代码如下 | 复制代码 |
newAlertDialog.Builder(EX03_12.this) .setTitle(R.string.app_about) .setMessage(R.string.app_about_msg) .setPositiveButton(R.string.str_ok, newDialogInterface.OnClickListener() { publicvoidonClick(DialogInterface dialoginterface,inti) { } }).show(); |
这里仅是有一个确定按钮,还可以添加其他的按钮和图标,可以参照Android文档。
2.提到AlertDialog,自然就会想到Toast。Toast就是一个简短的小信息,可以提示音量大小的调整等。对程序员来说,它也是一个非常好用的Debug工具。
代码如下 | 复制代码 |
/*使用系统标准的 makeText()方式来产生Toast讯息*/ Toast.makeText( EX04_03.this,String,Toast.LENGTH_LONG).show(); |
第三个参数可以是LENGTH_LONG或LENGTH_SHORT,前者表示时间长,后者较短。当然,也可以使用重写的Toast对象的方法,自己定义Toast显示的Layout。
小编推荐的这篇文章介绍了Android开发之菜单(menu)用法实例分析,非常实用,有兴趣的同学快来看看吧Android手机专门用一个按键“menu“来显示菜单。
要实现菜单功能,首先要通过方法onCreateOptionMenu来创建菜单,创建方法有两种:一种是直接导入有menu的xml文件,一种是用类Menu的方法直接添加。创建好菜单后,用事件监听器onOptionItemSelected对能够触发的事件进行监听。
下面这个例子有两个Activity,分别有上面的两种方法实现menu,每个menu里都有事件监听器进行Activity跳转和退出。
1.资源文件下的menu文件res/menu/menu.xml
代码如下 | 复制代码 |
<itemandroid:id="@+id/about" android:title="关于"/> <itemandroid:id="@+id/exit" android:title="退出"/> |
Activity01.Java
代码如下 | 复制代码 |
packagecom.yarin.android.Examples_04_13; importandroid.app.Activity; importandroid.content.Intent; importandroid.os.Bundle; importandroid.view.Menu; importandroid.view.MenuInflater; importandroid.view.MenuItem; publicclassActivity01extendsActivity { /** Called when the activity is first created. */ @Override publicvoidonCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } /*创建menu*/ public boolean onCreateOptionsMenu(Menu menu) { //MenuInflater class is used to instantiate menu XML files into Menu objects MenuInflater inflater = getMenuInflater(); //设置menu界面为res/menu/menu.xml inflater.inflate(R.menu.menu, menu); return true; } /*处理菜单事件*/ public boolean onOptionsItemSelected(MenuItem item) { //得到当前选中的MenuItem的ID, int item_id = item.getItemId(); switch (item_id) { case R.id.about: /* 新建一个Intent对象 */ Intent intent = new Intent(); /* 指定intent要启动的类 */ intent.setClass(Activity01.this, Activity02.class); /* 启动一个新的Activity */ startActivity(intent); /* 关闭当前的Activity */ Activity01.this.finish(); break; caseR.id.exit: Activity01.this.finish(); break; } returntrue; } } |
Activity02.java
代码如下 | 复制代码 |
packagecom.yarin.android.Examples_04_13; importandroid.app.Activity; importandroid.content.Intent; importandroid.os.Bundle; importandroid.view.Menu; importandroid.view.MenuItem; publicclassActivity02extendsActivity { publicvoidonCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /* 设置显示main2.xml布局 */ setContentView(R.layout.main2); } /*创建menu*/ public boolean onCreateOptionsMenu(Menu menu) { //为menu添加内容 menu.add(0, 0, 0, R.string.ok); menu.add(0, 1, 1, R.string.back); return true; } /*处理menu的事件*/ public boolean onOptionsItemSelected(MenuItem item) { //得到当前选中的MenuItem的ID, int item_id = item.getItemId(); switch (item_id) { case 0: case 1: /* 新建一个Intent对象 */ Intent intent = new Intent(); /* 指定intent要启动的类 */ intent.setClass(Activity02.this, Activity01.class); /* 启动一个新的Activity */ startActivity(intent); /* 关闭当前的Activity */ Activity02.this.finish(); break; } returntrue; } } |
本例用到了两个Activity,不要忘记在AndroidManifest.xml中声明。
相关文章
- 下面我们来看一篇关于Android子控件超出父控件的范围显示出来方法,希望这篇文章能够帮助到各位朋友,有碰到此问题的朋友可以进来看看哦。 <RelativeLayout xmlns:an...2016-10-02
- 这篇文章主要给大家介绍了关于C#创建自定义控件及添加自定义属性和事件使用的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用C#具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧...2020-06-25
- 本文实例讲述了JS实现自定义简单网页软键盘效果。分享给大家供大家参考,具体如下:这是一款自定义的简单点的网页软键盘,没有使用任何控件,仅是为了练习JavaScript编写水平,安全性方面没有过多考虑,有顾虑的可以不用,目的是学...2015-11-08
Android开发中findViewById()函数用法与简化
findViewById方法在android开发中是获取页面控件的值了,有没有发现我们一个页面控件多了会反复研究写findViewById呢,下面我们一起来看它的简化方法。 Android中Fin...2016-09-20- 如果我们的项目需要做来电及短信的功能,那么我们就得在Android模拟器开发这些功能,本来就来告诉我们如何在Android模拟器上模拟来电及来短信的功能。 在Android模拟...2016-09-20
- 夜神android模拟器如何设置代理呢?对于这个问题其实操作起来是非常的简单,下面小编来为各位详细介绍夜神android模拟器设置代理的方法,希望例子能够帮助到各位。 app...2016-09-20
- 为了增强android应用的用户体验,我们可以在一些Button按钮上自定义动态的设置一些样式,比如交互时改变字体、颜色、背景图等。 今天来看一个通过重写Button来动态实...2016-09-20
- 如果我们要在Android应用APP中加载html5页面,我们可以使用WebView,本文我们分享两个WebView加载html5页面实例应用。 实例一:WebView加载html5实现炫酷引导页面大多...2016-09-20
- 深入理解Android中View和ViewGroup从组成架构上看,似乎ViewGroup在View之上,View需要继承ViewGroup,但实际上不是这样的。View是基类,ViewGroup是它的子类。本教程我们深...2016-09-20
- 下面我们来看一篇关于Android自定义WebView网络视频播放控件开发例子,这个文章写得非常的不错下面给各位共享一下吧。 因为业务需要,以下代码均以Youtube网站在线视...2016-10-02
- 自定义一个jquery模态窗口插件,将它集成到现有平台框架中时,它只能在mainFrame窗口中显示,无法在顶层窗口显示. 解决这个问题的办法: 通过以下代码就可能实现在顶层窗口弹窗 复制代码 代码如下: $(window.top.documen...2014-05-31
- java开发的Android应用,性能一直是一个大问题,,或许是Java语言本身比较消耗内存。本文我们来谈谈Android 性能优化之MemoryFile文件读写。 Android匿名共享内存对外A...2016-09-20
- 这篇文章主要介绍了自定义feignClient的常见坑及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-10-20
- TextView默认是横着显示了,今天我们一起来看看Android设置TextView竖着显示如何来实现吧,今天我们就一起来看看操作细节,具体的如下所示。 在开发Android程序的时候,...2016-10-02
- 今天小编就为大家分享一篇pytorch 自定义卷积核进行卷积操作方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-05-06
android.os.BinderProxy cannot be cast to com解决办法
本文章来给大家介绍关于android.os.BinderProxy cannot be cast to com解决办法,希望此文章对各位有帮助呀。 Android在绑定服务的时候出现java.lang.ClassCastExc...2016-09-20- 这篇文章主要介绍了Android 实现钉钉自动打卡功能的步骤,帮助大家更好的理解和学习使用Android,感兴趣的朋友可以了解下...2021-03-15
PHP YII框架开发小技巧之模型(models)中rules自定义验证规则
YII的models中的rules部分是一些表单的验证规则,对于表单验证十分有用,在相应的视图(views)里面添加了表单,在表单被提交之前程序都会自动先来这里面的规则里验证,只有通过对其有效的限制规则后才能被提交,可以很有效地保证...2015-11-24- 下面我们来看一篇关于Android 开发之布局细节对比:RTL模式 ,希望这篇文章对各位同学会带来帮助,具体的细节如下介绍。 前言 讲真,好久没写博客了,2016都过了一半了,赶紧...2016-10-02
- 这篇文章主要介绍了jquery自定义插件开发之window的实现过程的相关资料,需要的朋友可以参考下...2016-05-09