Android自定义控制(五)仿新浪微博的下拉刷新

网上有很多很有名的开源框架,这里就来拉拉PullToRefresh这个框架,也就是我们平时用的下拉刷新啦,当然你问我这个有什么用啊?别人已经写好了,这里主要是学习以及练习,练习的次数多了,一切就顺其自然的会了.

废话少说,先上图,再上代码:


1.要想实现下拉刷新功能必须要有个下拉刷新的布局,是吧?

[html]  view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:orientation="vertical" >  
  6.       
  7.     <RelativeLayout  
  8.         android:layout_width="match_parent"  
  9.         android:layout_height="wrap_content"  
  10.         android:paddingBottom="10dip"  
  11.         android:paddingTop="10dip" >  
  12.   
  13.         <LinearLayout  
  14.             android:id="@+id/layout"  
  15.             android:layout_width="wrap_content"  
  16.             android:layout_height="wrap_content"  
  17.             android:layout_centerInParent="true"  
  18.             android:gravity="center"  
  19.             android:orientation="vertical" >  
  20.   
  21.             <TextView  
  22.                 android:id="@+id/tip"  
  23.                 android:layout_width="wrap_content"  
  24.                 android:layout_height="wrap_content"  
  25.                 android:text="@string/state" />  
  26.   
  27.             <TextView  
  28.                 android:id="@+id/lastupdate_time"  
  29.                 android:layout_width="wrap_content"  
  30.                 android:layout_height="wrap_content" />  
  31.         </LinearLayout>  
  32.   
  33.         <ProgressBar  
  34.             android:id="@+id/progress"  
  35.             style="?android:attr/progressBarStyleSmall"  
  36.             android:layout_width="wrap_content"  
  37.             android:layout_height="wrap_content"  
  38.             android:layout_toLeftOf="@id/layout"  
  39.             android:layout_marginRight="20dip"  
  40.             android:visibility="gone" />  
  41.   
  42.         <ImageView  
  43.             android:id="@+id/arrow"  
  44.             android:layout_width="wrap_content"  
  45.             android:layout_height="wrap_content"  
  46.             android:layout_alignTop="@+id/layout"  
  47.             android:layout_marginRight="19dp"  
  48.             android:layout_toLeftOf="@+id/layout"  
  49.             android:src="@drawable/arrow_down" />  
  50.   
  51.     </RelativeLayout>  
  52.   
  53. </LinearLayout>  

2.你要把它加入到布局里面吧!
[java]  view plain copy
  1. headView=layoutInflater.from(context).inflate(R.layout.header_layout, null);  
  2.         this.addHeaderView(headView);  
3.加入到布局直接显示出来也不符合需求啊,所以这一步需要隐藏布局,当然不能和前一篇博客( Android自定义控件(四)仿网易客户端上拉加载更多 )一样直接隐藏,直接隐藏满足不了如图的要求,我们这里采取的是设置头部布局的高度为实际高度的负值,这样就实现了隐藏功能,当下拉的时候,还不至于一次就全部显示出来,ok这种办法能够实现图中的要求
[java]  view plain copy
  1. headerHeight = headView.getMeasuredHeight();  
  2.         setHeaderViewHeight(-headerHeight);  


[java]  view plain copy
  1. /** 
  2.      * 设置头部布局的高度 
  3.      *  
  4.      * @param i 
  5.      */  
  6.     private void setHeaderViewHeight(int headerHeight) {  
  7.         headView.setPadding(headView.getPaddingLeft(), headerHeight,  
  8.                 headView.getPaddingRight(), headView.getPaddingBottom());  
  9.         //重绘  
  10.         headView.invalidate();  
  11.     }  

4.跑起来之后,白瞎了,没实现想要的功能,也就是说没有把头部布局隐藏掉,哎,跟踪代码之后发现高度为0,郭神说过在measure之前,getMeasureWidth()和getMeasureHeight()都为零,好吧,那就先measure吧!

[java]  view plain copy
  1. private void measureView(View view) {  
  2.         ViewGroup.LayoutParams lp = view.getLayoutParams();  
  3.         if (lp == null) {  
  4.             lp = new ViewGroup.LayoutParams(  
  5.                     ViewGroup.LayoutParams.MATCH_PARENT,  
  6.                     ViewGroup.LayoutParams.WRAP_CONTENT);  
  7.         }  
  8.         int width = ViewGroup.getChildMeasureSpec(00, lp.width);  
  9.         int height;  
  10.         int tempHeight=lp.height;  
  11.         if (tempHeight > 0) {  
  12.             height = MeasureSpec.makeMeasureSpec(tempHeight,  
  13.                     MeasureSpec.EXACTLY);  
  14.         } else {  
  15.             height = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);  
  16.         }  
  17.         view.measure(width, height);  
  18.     }  

5.隐藏成功了,下面就要实现具体的功能了,下拉刷新,松开刷新,正在刷新这三个状态,是通过手势改变状态,所以这里要实现onTouch,当然还有OnScrollListener

需要用到firstVisibleItem判断Listview向上滑动还是向下滑动,如果firstVisibleItem==0说明到达ListView的头部了,当然你还需要一个布尔值判断是否按下滑动

[java]  view plain copy
  1. @Override  
  2.     public void onScroll(AbsListView view, int firstVisibleItem,  
  3.             int visibleItemCount, int totalItemCount) {  
  4.         this.firstVisibleItem=firstVisibleItem;  
  5.     }  


重写onTouchEvent,通过firstVisibleItem和布尔值判断按下,抬起,滑动

[java]  view plain copy
  1. @Override  
  2.     public boolean onTouchEvent(MotionEvent ev) {  
  3.         switch (ev.getAction()) {  
  4.         case MotionEvent.ACTION_DOWN:  
  5.             if (firstVisibleItem == 0) {  
  6.                 isRemark = true;  
  7.                 startY = (int) ev.getY();  
  8.             }  
  9.             break;  
  10.   
  11.         case MotionEvent.ACTION_MOVE:  
  12.             onMove(ev);  
  13.             break;  
  14.   
  15.         case MotionEvent.ACTION_UP:  
  16.             if (state==RELEASE) {  
  17.                 state=REFRASH;  
  18.                 reflashViewByState();  
  19.                 //更新数据  
  20.                 isRefreshListener.onRefresh();  
  21.             }else if (state==PULL) {  
  22.                 state=NONE;  
  23.                 isRemark=false;  
  24.                 refreshDrawableState();  
  25.             }  
  26.             break;  
  27.         }  
  28.         return super.onTouchEvent(ev);  
  29.     }  

代码不全,先解释一下,后面附上全部代码

按下时,如果firstVisibleItem为0,说明到达listview的顶部,并且可以按下,把isRemark赋值为true,滑动时改变头部布局的状态

[java]  view plain copy
  1. /** 
  2.      * 移动过程的状态变换 
  3.      *  
  4.      * @param ev 
  5.      */  
  6.     private void onMove(MotionEvent ev) {  
  7.         if (!isRemark) {  
  8.             return;  
  9.         }  
  10.         int tempY = (int) ev.getY();  
  11.         int space = tempY - startY;  
  12.         int topPadding = space - headerHeight;  
  13.         switch (state) {  
  14.         case NONE:  
  15.             if (space>0) {  
  16.                 state=PULL;  
  17.                 reflashViewByState();  
  18.             }  
  19.             break;  
  20.   
  21.         case PULL:  
  22.             setHeaderViewHeight(topPadding);  
  23.             if (space>headerHeight+30&&scrollState==SCROLL_STATE_IDLE) {  
  24.                 state=RELEASE;  
  25.                 reflashViewByState();  
  26.             }  
  27.             break;  
  28.   
  29.         case RELEASE:  
  30.             setHeaderViewHeight(topPadding);  
  31.             if (space<headerHeight+30) {  
  32.                 state=PULL;  
  33.                 reflashViewByState();  
  34.             }else if (space<=0) {  
  35.                 state=NONE;  
  36.                 reflashViewByState();  
  37.             }  
  38.             break;  
  39.               
  40.         }  
  41.     }  

根据滑动之后和动画前y值的变化判断滑动状态,当space大于零时,当前状态变为下拉刷新,如果space大于某个值时,当前状态变为松开可以刷新,当space大于零小于某个值时,当前状态为下拉刷新状态,当space小于零时,当前状态变为正常状态.当然状态改变时,界面也要随着改变
[java]  view plain copy
  1. /** 
  2.      *根据状态刷新当前页面 
  3.      */  
  4.     private void reflashViewByState() {  
  5.         TextView tip = (TextView) headView.findViewById(R.id.tip);  
  6.         ImageView arrow = (ImageView) headView.findViewById(R.id.arrow);  
  7.         ProgressBar progress = (ProgressBar) headView.findViewById(R.id.progress);  
  8.         RotateAnimation anim = new RotateAnimation(0180,  
  9.                 RotateAnimation.RELATIVE_TO_SELF, 0.5f,  
  10.                 RotateAnimation.RELATIVE_TO_SELF, 0.5f);  
  11.         anim.setDuration(500);  
  12.         anim.setFillAfter(true);  
  13.         RotateAnimation anim1 = new RotateAnimation(1800,  
  14.                 RotateAnimation.RELATIVE_TO_SELF, 0.5f,  
  15.                 RotateAnimation.RELATIVE_TO_SELF, 0.5f);  
  16.         anim1.setDuration(500);  
  17.         anim1.setFillAfter(true);  
  18.         switch (state) {  
  19.         case NONE:  
  20.             setHeaderViewHeight(-headerHeight);  
  21.             arrow.clearAnimation();  
  22.             break;  
  23.               
  24.         case PULL:  
  25.             arrow.setVisibility(View.VISIBLE);  
  26.             progress.setVisibility(View.GONE);  
  27.             tip.setText("下拉刷新");  
  28.             arrow.clearAnimation();  
  29.             arrow.setAnimation(anim1);  
  30.             break;  
  31.   
  32.         case RELEASE:  
  33.             arrow.setVisibility(View.VISIBLE);  
  34.             progress.setVisibility(View.GONE);  
  35.             tip.setText("松开刷新");  
  36.             arrow.clearAnimation();  
  37.             arrow.setAnimation(anim);  
  38.             break;  
  39.               
  40.         case REFRASH:  
  41.             setHeaderViewHeight(50);  
  42.             arrow.setVisibility(View.GONE);  
  43.             progress.setVisibility(View.VISIBLE);  
  44.             tip.setText("正在刷新");  
  45.             arrow.clearAnimation();  
  46.             break;  
  47.         }  
  48.     }  

界面上主要改变的就是提示,箭头和progress,正常状态下,界面不可见,下拉刷新状态下,箭头可见并且朝下,提示信息为下拉刷新并且progress不可见,松开刷新状态,箭头朝上,progress不可见,提示信息为下拉刷新,正在加载状态箭头不可见,progress可见,提示信息改为正在刷新

当然,在变成正在加载状态时,还要加载更过数据

[java]  view plain copy
  1. public interface IsRefreshListener{  
  2.         public void onRefresh();  
  3.     }  
  4.       
  5.     public void setIsRefreshListener(IsRefreshListener isRefreshListener){  
  6.         this.isRefreshListener=isRefreshListener;  
  7.     }  

加载完数据后,还要通知listview刷新结束
[java]  view plain copy
  1. /** 
  2.      * 获取完数据; 
  3.      */  
  4.     public void reflashComplete() {  
  5.         state = NONE;  
  6.         isRemark = false;  
  7.         reflashViewByState();  
  8.         TextView lastupdatetime = (TextView) headView  
  9.                 .findViewById(R.id.lastupdate_time);  
  10.         SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss");  
  11.         Date date = new Date(System.currentTimeMillis());  
  12.         String time = format.format(date);  
  13.         lastupdatetime.setText(time);  
  14.     }  

自定义下拉刷新控件就这样完成了,不懂得留言吧,我尽量给你解答,自定义这东西,写多了也就知道怎么写了

下面附上自定义下拉刷新控件的全部代码:

[java]  view plain copy
  1. package com.sdufe.thea.guo.view;  
  2.   
  3. import java.text.SimpleDateFormat;  
  4. import java.util.Date;  
  5.   
  6. import android.content.Context;  
  7. import android.util.AttributeSet;  
  8. import android.view.LayoutInflater;  
  9. import android.view.MotionEvent;  
  10. import android.view.View;  
  11. import android.view.ViewGroup;  
  12. import android.view.animation.RotateAnimation;  
  13. import android.widget.AbsListView;  
  14. import android.widget.ImageView;  
  15. import android.widget.ProgressBar;  
  16. import android.widget.TextView;  
  17. import android.widget.AbsListView.OnScrollListener;  
  18. import android.widget.ListView;  
  19.   
  20. import com.sdufe.thea.guo.R;  
  21.   
  22. public class PullToRefreshListView extends ListView implements OnScrollListener {  
  23.   
  24.     View headView;  
  25.     int headerHeight;  
  26.     int firstVisibleItem;  
  27.     int scrollState;  
  28.     boolean isRemark;  
  29.     int startY;  
  30.   
  31.     int state;  
  32.     final int NONE = 0;  
  33.     final int PULL = 1;  
  34.     final int RELEASE = 2;  
  35.     final int REFRASH = 3;  
  36.       
  37.     IsRefreshListener isRefreshListener;  
  38.   
  39.     public PullToRefreshListView(Context context, AttributeSet attrs,  
  40.             int defStyle) {  
  41.         super(context, attrs, defStyle);  
  42.         initView(context);  
  43.     }  
  44.   
  45.     public PullToRefreshListView(Context context, AttributeSet attrs) {  
  46.         super(context, attrs);  
  47.         initView(context);  
  48.     }  
  49.   
  50.     public PullToRefreshListView(Context context) {  
  51.         super(context);  
  52.         initView(context);  
  53.     }  
  54.   
  55.     private void initView(Context context) {  
  56.         headView = LayoutInflater.from(context).inflate(R.layout.header_layout,  
  57.                 null);  
  58.         measureView(headView);  
  59.         headerHeight = headView.getMeasuredHeight();  
  60.         setHeaderViewHeight(-headerHeight);  
  61.         addView(headView);  
  62.         setOnScrollListener(this);  
  63.     }  
  64.   
  65.     /** 
  66.      * 计算宽高 
  67.      *  
  68.      * @param view 
  69.      */  
  70.     private void measureView(View view) {  
  71.         ViewGroup.LayoutParams lp = view.getLayoutParams();  
  72.         if (lp == null) {  
  73.             lp = new ViewGroup.LayoutParams(  
  74.                     ViewGroup.LayoutParams.MATCH_PARENT,  
  75.                     ViewGroup.LayoutParams.WRAP_CONTENT);  
  76.         }  
  77.         int width = ViewGroup.getChildMeasureSpec(00, lp.width);  
  78.         int height;  
  79.         int tempHeight = lp.height;  
  80.         if (tempHeight > 0) {  
  81.             height = MeasureSpec.makeMeasureSpec(tempHeight,  
  82.                     MeasureSpec.EXACTLY);  
  83.         } else {  
  84.             height = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);  
  85.         }  
  86.         view.measure(width, height);  
  87.     }  
  88.   
  89.     /** 
  90.      * 设置头部布局的高度 
  91.      *  
  92.      * @param i 
  93.      */  
  94.     private void setHeaderViewHeight(int headerHeight) {  
  95.         headView.setPadding(headView.getPaddingLeft(), headerHeight,  
  96.                 headView.getPaddingRight(), headView.getPaddingBottom());  
  97.         // 重绘  
  98.         headView.invalidate();  
  99.     }  
  100.   
  101.     @Override  
  102.     public void onScrollStateChanged(AbsListView view, int scrollState) {  
  103.         this.scrollState = scrollState;  
  104.     }  
  105.   
  106.     @Override  
  107.     public void onScroll(AbsListView view, int firstVisibleItem,  
  108.             int visibleItemCount, int totalItemCount) {  
  109.         this.firstVisibleItem = firstVisibleItem;  
  110.     }  
  111.   
  112.     @Override  
  113.     public boolean onTouchEvent(MotionEvent ev) {  
  114.         switch (ev.getAction()) {  
  115.         case MotionEvent.ACTION_DOWN:  
  116.             if (firstVisibleItem == 0) {  
  117.                 isRemark = true;  
  118.                 startY = (int) ev.getY();  
  119.             }  
  120.             break;  
  121.   
  122.         case MotionEvent.ACTION_MOVE:  
  123.             onMove(ev);  
  124.             break;  
  125.   
  126.         case MotionEvent.ACTION_UP:  
  127.             if (state==RELEASE) {  
  128.                 state=REFRASH;  
  129.                 reflashViewByState();  
  130.                 //更新数据  
  131.                 isRefreshListener.onRefresh();  
  132.             }else if (state==PULL) {  
  133.                 state=NONE;  
  134.                 isRemark=false;  
  135.                 refreshDrawableState();  
  136.             }  
  137.             break;  
  138.         }  
  139.         return super.onTouchEvent(ev);  
  140.     }  
  141.   
  142.     /** 
  143.      * 移动过程的状态变换 
  144.      *  
  145.      * @param ev 
  146.      */  
  147.     private void onMove(MotionEvent ev) {  
  148.         if (!isRemark) {  
  149.             return;  
  150.         }  
  151.         int tempY = (int) ev.getY();  
  152.         int space = tempY - startY;  
  153.         int topPadding = space - headerHeight;  
  154.         switch (state) {  
  155.         case NONE:  
  156.             if (space>0) {  
  157.                 state=PULL;  
  158.                 reflashViewByState();  
  159.             }  
  160.             break;  
  161.   
  162.         case PULL:  
  163.             setHeaderViewHeight(topPadding);  
  164.             if (space>headerHeight+30&&scrollState==SCROLL_STATE_IDLE) {  
  165.                 state=RELEASE;  
  166.                 reflashViewByState();  
  167.             }  
  168.             break;  
  169.   
  170.         case RELEASE:  
  171.             setHeaderViewHeight(topPadding);  
  172.             if (space<headerHeight+30) {  
  173.                 state=PULL;  
  174.                 reflashViewByState();  
  175.             }else if (space<=0) {  
  176.                 state=NONE;  
  177.                 reflashViewByState();  
  178.             }  
  179.             break;  
  180.               
  181.         }  
  182.     }  
  183.       
  184.     /** 
  185.      * 获取完数据; 
  186.      */  
  187.     public void reflashComplete() {  
  188.         state = NONE;  
  189.         isRemark = false;  
  190.         reflashViewByState();  
  191.         TextView lastupdatetime = (TextView) headView  
  192.                 .findViewById(R.id.lastupdate_time);  
  193.         SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss");  
  194.         Date date = new Date(System.currentTimeMillis());  
  195.         String time = format.format(date);  
  196.         lastupdatetime.setText(time);  
  197.     }  
  198.   
  199.     /** 
  200.      *根据状态刷新当前页面 
  201.      */  
  202.     private void reflashViewByState() {  
  203.         TextView tip = (TextView) headView.findViewById(R.id.tip);  
  204.         ImageView arrow = (ImageView) headView.findViewById(R.id.arrow);  
  205.         ProgressBar progress = (ProgressBar) headView.findViewById(R.id.progress);  
  206.         RotateAnimation anim = new RotateAnimation(0180,  
  207.                 RotateAnimation.RELATIVE_TO_SELF, 0.5f,  
  208.                 RotateAnimation.RELATIVE_TO_SELF, 0.5f);  
  209.         anim.setDuration(500);  
  210.         anim.setFillAfter(true);  
  211.         RotateAnimation anim1 = new RotateAnimation(1800,  
  212.                 RotateAnimation.RELATIVE_TO_SELF, 0.5f,  
  213.                 RotateAnimation.RELATIVE_TO_SELF, 0.5f);  
  214.         anim1.setDuration(500);  
  215.         anim1.setFillAfter(true);  
  216.         switch (state) {  
  217.         case NONE:  
  218.             setHeaderViewHeight(-headerHeight);  
  219.             arrow.clearAnimation();  
  220.             break;  
  221.               
  222.         case PULL:  
  223.             arrow.setVisibility(View.VISIBLE);  
  224.             progress.setVisibility(View.GONE);  
  225.             tip.setText("下拉刷新");  
  226.             arrow.clearAnimation();  
  227.             arrow.setAnimation(anim1);  
  228.             break;  
  229.   
  230.         case RELEASE:  
  231.             arrow.setVisibility(View.VISIBLE);  
  232.             progress.setVisibility(View.GONE);  
  233.             tip.setText("松开刷新");  
  234.             arrow.clearAnimation();  
  235.             arrow.setAnimation(anim);  
  236.             break;  
  237.               
  238.         case REFRASH:  
  239.             setHeaderViewHeight(50);  
  240.             arrow.setVisibility(View.GONE);  
  241.             progress.setVisibility(View.VISIBLE);  
  242.             tip.setText("正在刷新");  
  243.             arrow.clearAnimation();  
  244.             break;  
  245.         }  
  246.     }  
  247.   
  248.     public interface IsRefreshListener{  
  249.         public void onRefresh();  
  250.     }  
  251.       
  252.     public void setIsRefreshListener(IsRefreshListener isRefreshListener){  
  253.         this.isRefreshListener=isRefreshListener;  
  254.     }  
  255. }  
下面就是怎么用了
[html]  view plain copy
  1. <com.sdufe.thea.guo.view.PullToRefreshListView  
  2.         android:id="@+id/pull_to_refresh"  
  3.         android:layout_width="match_parent"  
  4.         android:layout_height="wrap_content"/>  
下面的用法就跟listview差不多了,提示一点要实现IsRefreshListener接口,在onRefresh()里面加载更多数据

[java]  view plain copy
  1. package com.sdufe.thea.guo;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. import com.sdufe.thea.guo.view.PullToRefreshListView;  
  7. import com.sdufe.thea.guo.view.PullToRefreshListView.IsRefreshListener;  
  8.   
  9. import android.os.Bundle;  
  10. import android.app.Activity;  
  11. import android.view.Menu;  
  12. import android.widget.ArrayAdapter;  
  13.   
  14. public class MainActivity extends Activity implements IsRefreshListener{  
  15.   
  16.     PullToRefreshListView listView;  
  17.     ArrayAdapter<String> adapter;  
  18.     List<String> list;  
  19.   
  20.     @Override  
  21.     protected void onCreate(Bundle savedInstanceState) {  
  22.         super.onCreate(savedInstanceState);  
  23.         setContentView(R.layout.activity_main);  
  24.   
  25.         listView = (PullToRefreshListView) findViewById(R.id.pull_to_refresh);  
  26.         initData();  
  27.         adapter = new ArrayAdapter<String>(this,  
  28.                 android.R.layout.simple_list_item_1, list);  
  29.         listView.setAdapter(adapter);  
  30.     }  
  31.   
  32.     private void initData() {  
  33.         list = new ArrayList<String>();  
  34.         list.add("123456789");  
  35.         list.add("123456789");  
  36.         list.add("123456789");  
  37.     }  
  38.   
  39.     @Override  
  40.     public void onRefresh() {  
  41.         list.add("爸爸");  
  42.         list.add("妈妈");  
  43.         list.add("我");  
  44.             adapter.notifyDataSetChanged();  
  45.         listView.reflashComplete();  
  46.     }  
  47.   
  48. }  

今天就到此结束啦,不懂的,留言
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下拉菜单通常是通过CSS和JavaScript实现的。下面是一个简单的示例代码,可以实现一个类似新浪微博的下拉菜单: HTML部分: ```html <div class="dropdown"> <button class="dropbtn">菜单</button> <div class="dropdown-content"> <a href="#">选项1</a> <a href="#">选项2</a> <a href="#">选项3</a> </div> </div> ``` CSS部分: ```css .dropdown { position: relative; display: inline-block; } .dropbtn { background-color: #fff; border: none; color: #333; padding: 10px 15px; font-size: 16px; cursor: pointer; } .dropdown-content { display: none; position: absolute; z-index: 1; background-color: #fff; box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2); } .dropdown-content a { color: #333; padding: 12px 16px; text-decoration: none; display: block; } .dropdown:hover .dropdown-content { display: block; } ``` JavaScript部分: ```javascript // 点击菜单按钮时显示或隐藏下拉菜单 document.querySelector('.dropbtn').addEventListener('click', function () { document.querySelector('.dropdown-content').classList.toggle('show'); }); // 点击菜单外部时隐藏下拉菜单 window.addEventListener('click', function (event) { if (!event.target.matches('.dropbtn')) { var dropdowns = document.querySelectorAll('.dropdown-content'); for (var i = 0; i < dropdowns.length; i++) { var dropdown = dropdowns[i]; if (dropdown.classList.contains('show')) { dropdown.classList.remove('show'); } } } }); ``` 这段代码中,我们给按钮添加了一个点击事件,当点击按钮时,显示或隐藏下拉菜单。同时,我们也添加了一个全局点击事件,当用户点击菜单外部时,隐藏下拉菜单。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值