zoukankan      html  css  js  c++  java
  • Android中实现下拉刷新

    需求:项目中的消息列表界面要求实现类似sina微博的下拉刷新;

    思路:一般的消息列表为ListView类型,将list加载到adapter中,再将adapter加载到 ListView中,从而实现消息列表的展示。而下拉刷新要求给消息列表加一个头部,其中有图片(向上/向下箭头)和提示字样(下拉刷新/松开刷新),从 而我们需要做的事情:1.需要做一个head.xm来实现头部的样式定义;2.需要自定义一个继承了ListView的MsgListView,在该类中 将head加在MsgListView对象的头部;3.将原有的消息界面布局文件中的ListView改为 cn.xd.microblogging.tools.MsgListView(包名.MsgListView);4.将原有的消息界面后台代码中创建的 ListView对象改为MsgListView对象,注意消息界面Activity要继承ListActivity,并且实现其刷新监听。

    说明:实现下拉刷新很简单,仅需要4个文件:MsgRcvListActivity.java(消息列表界面的后台文件,真正的刷新动作在这里完成,下拉刷新相关code下面列出),msgrcvlistactivity.xml(消息列表界面的前台文件,下拉刷新相关code下面列出),MsgListView.java(本文件拿来主义即可不用改,下拉刷新自定义的列表类,监听并执行下拉刷新、松开刷新、正在刷新、完成刷新等状态的改变,但真正的刷新动作不在这里完成,完整code下面列出),head.xml(本文件拿来主义即可不用改,下拉刷新的样式定义文件,包括向上、向下箭头,刷新状态提示等,完整code下面列出);

    效果

    EyeAndroid.com31404201203260021061.gif

    代码

    1.MsgRcvListActivity.java :

     
    1. public class MsgRcvListActivity extends ListActivity {//注意:要继承ListActivity  
    2.     …………//变量定义,略  
    3.     MsgListView list;  
    4.     @Override  
    5.     protected void onCreate(Bundle savedInstanceState) {  
    6.         super.onCreate(savedInstanceState);  
    7.         setContentView(R.layout.msgrcvlistactivity);      
    8.         list=(MsgListView)findViewById(android.R.id.list);//继承ListActivity,id要写成android.R.id.list,否则报异常  
    9.         …………//其他代码,略  
    10.                    //刷新监听,此处实现真正刷新  
    11.                list.setonRefreshListener(new OnRefreshListener() {  
    12.             public void onRefresh() {  
    13.                 new AsyncTask<Void, Void, Void>() {  
    14.                     protected Void doInBackground(Void... params) {  
    15.                         try {  
    16.                             Thread.sleep(1000);  
    17.                         } catch (Exception e) {  
    18.                             e.printStackTrace();  
    19.                         }  
    20.                         return null;  
    21.                     }  
    22.   
    23.                     @Override  
    24.                     protected void onPostExecute(Void result) {  
    25.                         adapter.notifyDataSetChanged();  
    26.                         new MsgLoad().execute();//刷新监听中,真正执行刷新动作  
    27.                         list.onRefreshComplete();  
    28.                     }  
    29.                 }.execute(null);  
    30.             }  
    31.         });  
    32.         list.setItemsCanFocus(false);              
    33.         list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);  
    34.     }  
    35.     …………//其他代码,略  
    36.     public class MsgLoad extends AsyncTask<Void, Void, List<MsgBean>> {  
    37.         …………//其他代码,略  
    38.     }  
    39. }  

     

    2.msgrcvlistactivity.xml:

     
    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <RelativeLayout  
    3.   xmlns:android="http://schemas.android.com/apk/res/android"  
    4.   android:layout_width="fill_parent"  
    5.   android:layout_height="fill_parent"  
    6.   >  
    7.   <LinearLayout android:orientation="vertical"  
    8.                 android:layout_width="fill_parent"  
    9.                 android:layout_height="fill_parent"  
    10.                 android:background="#000000">         
    11.         //将ListView改为包名.自定义的列表类名,MsgListView.java代码见后,此代码不需改通用,下拉刷新相关即此处,其他无关  
    12.         <cn.xd.microblogging.tools.MsgListView  
    13.         android:id="@android:id/list"  
    14.         android:layout_height="wrap_content"  
    15.         android:layout_width="fill_parent"  
    16.         android:layout_weight="1.0"  
    17.         android:drawSelectorOnTop="false"  
    18.         android:scrollbars="vertical"  
    19.         android:fadingEdgeLength="0dip"   
    20.         android:divider="@drawable/line"  
    21.         android:dividerHeight="3.0dip"  
    22.         android:cacheColorHint="#00000000"   
    23.         android:paddingBottom="40dp"/>  
    24.   </LinearLayout>  
    25.   <LinearLayout  
    26.       android:id="@+id/msg_list_load"  
    27.       android:layout_width="fill_parent"  
    28.       android:layout_height="fill_parent" >        
    29.     <LinearLayout android:id="@android:id/empty"  
    30.                   android:layout_width="fill_parent"  
    31.                   android:layout_height="fill_parent" >         
    32.       <include  
    33.         android:id="@android:id/empty"  
    34.         layout="@layout/empty_loading"  
    35.         android:layout_width="fill_parent"  
    36.         android:layout_height="fill_parent" />        
    37.      </LinearLayout>  
    38.   </LinearLayout>  
    39. </RelativeLayout>  

     

    3.MsgListView.java,拷进项目基本不需改:

     
    1. package cn.xd.microblogging.tools;  
    2.   
    3. import java.util.Date;  
    4.   
    5. import cn.xd.microblogging.R;  
    6.   
    7. import android.content.Context;  
    8. import android.util.AttributeSet;  
    9. import android.util.Log;  
    10. import android.view.LayoutInflater;  
    11. import android.view.MotionEvent;  
    12. import android.view.View;  
    13. import android.view.ViewGroup;  
    14. import android.view.animation.LinearInterpolator;  
    15. import android.view.animation.RotateAnimation;  
    16. import android.widget.AbsListView;  
    17. import android.widget.BaseAdapter;  
    18. import android.widget.ImageView;  
    19. import android.widget.LinearLayout;  
    20. import android.widget.ListView;  
    21. import android.widget.AbsListView.OnScrollListener;  
    22. import android.widget.ProgressBar;  
    23. import android.widget.TextView;  
    24.   
    25. /** 
    26.  *  
    27.  * 自定义MsgListView,继承了ListView, 
    28.  * 但填充了listview的头部,即下拉刷新样式,并实现其功能 
    29.  * @author yanbo 
    30.  * 
    31.  */  
    32.   
    33. public class MsgListView extends ListView implements OnScrollListener {  
    34.      private final static int RELEASE_To_REFRESH = 0;  
    35.      private final static int PULL_To_REFRESH = 1;  
    36.      private final static int REFRESHING = 2;  
    37.      private final static int DONE = 3;  
    38.   
    39.      private LayoutInflater inflater;  
    40.   
    41.      private LinearLayout headView; // 头部  
    42.   
    43.      private TextView tipsTextview;//下拉刷新  
    44.      private TextView lastUpdatedTextView;//最新更新  
    45.      private ImageView arrowImageView;//箭头  
    46.      private ProgressBar progressBar;//刷新进度条  
    47.   
    48.      private RotateAnimation animation;//旋转特效 刷新中箭头翻转 向下变向上  
    49.      private RotateAnimation reverseAnimation;  
    50.   
    51.      // 用于保证startY的值在一个完整的touch事件中只被记录一次  
    52.      private boolean isRecored;  
    53.   
    54.      private int headContentWidth;//头部宽度  
    55.      private int headContentHeight;//头部高度  
    56.   
    57.      private int startY;//高度起始位置,用来记录与头部距离  
    58.      private int firstItemIndex;//列表中首行索引,用来记录其与头部距离  
    59.   
    60.      private int state;//下拉刷新中、松开刷新中、正在刷新中、完成刷新  
    61.   
    62.      private boolean isBack;  
    63.   
    64.      public OnRefreshListener refreshListener;//刷新监听  
    65.   
    66.      private final static String TAG = "abc";  
    67.   
    68.      public MsgListView(Context context, AttributeSet attrs) {  
    69.       super(context, attrs);  
    70.       init(context);  
    71.      }  
    72.   
    73.      private void init(Context context) {  
    74.       inflater = LayoutInflater.from(context);  
    75.   
    76.       headView = (LinearLayout) inflater.inflate(R.layout.head, null);//listview拼接headview  
    77.   
    78.       arrowImageView = (ImageView) headView  
    79.         .findViewById(R.id.head_arrowImageView);//headview中各view  
    80.       arrowImageView.setMinimumWidth(50);  
    81.       arrowImageView.setMinimumHeight(50);  
    82.       progressBar = (ProgressBar) headView  
    83.         .findViewById(R.id.head_progressBar);//headview中各view  
    84.       tipsTextview = (TextView) headView.findViewById(R.id.head_tipsTextView);//headview中各view  
    85.       lastUpdatedTextView = (TextView) headView  
    86.         .findViewById(R.id.head_lastUpdatedTextView);//headview中各view  
    87.   
    88.       measureView(headView);  
    89.       headContentHeight = headView.getMeasuredHeight();//头部高度  
    90.       headContentWidth = headView.getMeasuredWidth();//头部宽度  
    91.   
    92.       headView.setPadding(0, -1 * headContentHeight, 00);//setPadding(int left, int top, int right, int bottom)   
    93.       headView.invalidate();//Invalidate the whole view  
    94.   
    95.       Log.v("size""" + headContentWidth + " height:"  
    96.         + headContentHeight);  
    97.   
    98.       addHeaderView(headView);//添加进headview  
    99.       setOnScrollListener(this);//滚动监听  
    100.   
    101.       animation = new RotateAnimation(0, -180,  
    102.         RotateAnimation.RELATIVE_TO_SELF, 0.5f,  
    103.         RotateAnimation.RELATIVE_TO_SELF, 0.5f);  
    104.       animation.setInterpolator(new LinearInterpolator());  
    105.       animation.setDuration(250);  
    106.       animation.setFillAfter(true);//特效animation设置  
    107.   
    108.       reverseAnimation = new RotateAnimation(-1800,  
    109.         RotateAnimation.RELATIVE_TO_SELF, 0.5f,  
    110.         RotateAnimation.RELATIVE_TO_SELF, 0.5f);  
    111.       reverseAnimation.setInterpolator(new LinearInterpolator());  
    112.       reverseAnimation.setDuration(250);  
    113.       reverseAnimation.setFillAfter(true);//特效reverseAnimation设置  
    114.      }  
    115.   
    116.      public void onScroll(AbsListView arg0, int firstVisiableItem, int arg2,//滚动事件  
    117.        int arg3) {  
    118.       firstItemIndex = firstVisiableItem;//得到首item索引  
    119.      }  
    120.   
    121.      public void onScrollStateChanged(AbsListView arg0, int arg1) {  
    122.      }  
    123.   
    124.      public boolean onTouchEvent(MotionEvent event) {//触摸事件  
    125.       switch (event.getAction()) {  
    126.       case MotionEvent.ACTION_DOWN://手按下  对应下拉刷新状态  
    127.        if (firstItemIndex == 0 && !isRecored) {//如果首item索引为0,且尚未记录startY,则在下拉时记录之,并执行isRecored = true;  
    128.         startY = (int) event.getY();  
    129.         isRecored = true;  
    130.   
    131.         Log.v(TAG, "在down时候记录当前位置‘");  
    132.        }  
    133.        break;  
    134.   
    135.       case MotionEvent.ACTION_UP://手松开  对应松开刷新状态  
    136.   
    137.        if (state != REFRESHING) {//手松开有4个状态:下拉刷新、松开刷新、正在刷新、完成刷新。如果当前不是正在刷新  
    138.         if (state == DONE) {//如果当前是完成刷新,什么都不做  
    139.         }  
    140.         if (state == PULL_To_REFRESH) {//如果当前是下拉刷新,状态设为完成刷新(意即下拉刷新中就松开了,实际未完成刷新),执行changeHeaderViewByState()  
    141.          state = DONE;  
    142.          changeHeaderViewByState();  
    143.   
    144.          Log.v(TAG, "由下拉刷新状态,到done状态");  
    145.         }  
    146.         if (state == RELEASE_To_REFRESH) {//如果当前是松开刷新,状态设为正在刷新(意即松开刷新中松开手,才是真正地刷新),执行changeHeaderViewByState()  
    147.          state = REFRESHING;  
    148.          changeHeaderViewByState();  
    149.          onRefresh();//真正刷新,所以执行onrefresh,执行后状态设为完成刷新  
    150.   
    151.          Log.v(TAG, "由松开刷新状态,到done状态");  
    152.         }  
    153.        }  
    154.   
    155.        isRecored = false;//手松开,则无论怎样,可以重新记录startY,因为只要手松开就认为一次刷新已完成  
    156.        isBack = false;  
    157.   
    158.        break;  
    159.   
    160.       case MotionEvent.ACTION_MOVE://手拖动,拖动过程中不断地实时记录当前位置  
    161.        int tempY = (int) event.getY();  
    162.        if (!isRecored && firstItemIndex == 0) {//如果首item索引为0,且尚未记录startY,则在拖动时记录之,并执行isRecored = true;  
    163.         Log.v(TAG, "在move时候记录下位置");  
    164.         isRecored = true;  
    165.         startY = tempY;  
    166.        }  
    167.        if (state != REFRESHING && isRecored) {//如果状态不是正在刷新,且已记录startY:tempY为拖动过程中一直在变的高度,startY为拖动起始高度  
    168.         // 可以松手去刷新了  
    169.         if (state == RELEASE_To_REFRESH) {//如果状态是松开刷新  
    170.          // 往上推了,推到了屏幕足够掩盖head的程度,但是还没有推到全部掩盖的地步  
    171.          if ((tempY - startY < headContentHeight)//如果实时高度大于起始高度,且两者之差小于头部高度,则状态设为下拉刷新  
    172.            && (tempY - startY) > 0) {  
    173.           state = PULL_To_REFRESH;  
    174.           changeHeaderViewByState();  
    175.   
    176.           Log.v(TAG, "由松开刷新状态转变到下拉刷新状态");  
    177.          }  
    178.          // 一下子推到顶了  
    179.          else if (tempY - startY <= 0) {//如果实时高度小于等于起始高度了,则说明到顶了,状态设为完成刷新  
    180.           state = DONE;  
    181.           changeHeaderViewByState();  
    182.   
    183.           Log.v(TAG, "由松开刷新状态转变到done状态");  
    184.          }  
    185.          // 往下拉了,或者还没有上推到屏幕顶部掩盖head的地步  
    186.          else {//如果当前拖动过程中既没有到下拉刷新的地步,也没有到完成刷新(到顶)的地步,则保持松开刷新状态  
    187.           // 不用进行特别的操作,只用更新paddingTop的值就行了  
    188.          }  
    189.         }  
    190.         // 还没有到达显示松开刷新的时候,DONE或者是PULL_To_REFRESH状态  
    191.         if (state == PULL_To_REFRESH) {//如果状态是下拉刷新  
    192.          // 下拉到可以进入RELEASE_TO_REFRESH的状态  
    193.          if (tempY - startY >= headContentHeight) {//如果实时高度与起始高度之差大于等于头部高度,则状态设为松开刷新  
    194.           state = RELEASE_To_REFRESH;  
    195.           isBack = true;  
    196.           changeHeaderViewByState();  
    197.   
    198.           Log.v(TAG, "由done或者下拉刷新状态转变到松开刷新");  
    199.          }  
    200.          // 上推到顶了  
    201.          else if (tempY - startY <= 0) {//如果实时高度小于等于起始高度了,则说明到顶了,状态设为完成刷新  
    202.           state = DONE;  
    203.           changeHeaderViewByState();  
    204.   
    205.           Log.v(TAG, "由DOne或者下拉刷新状态转变到done状态");  
    206.          }  
    207.         }  
    208.   
    209.         // done状态下  
    210.         if (state == DONE) {//如果状态是完成刷新  
    211.          if (tempY - startY > 0) {//如果实时高度大于起始高度了,则状态设为下拉刷新  
    212.           state = PULL_To_REFRESH;  
    213.           changeHeaderViewByState();  
    214.          }  
    215.         }  
    216.   
    217.         // 更新headView的size  
    218.         if (state == PULL_To_REFRESH) {//如果状态是下拉刷新,更新headview的size           ?  
    219.          headView.setPadding(0, -1 * headContentHeight  
    220.            + (tempY - startY), 00);  
    221.          headView.invalidate();  
    222.         }  
    223.   
    224.         // 更新headView的paddingTop  
    225.         if (state == RELEASE_To_REFRESH) {//如果状态是松开刷新,更新 headview的paddingtop      ?  
    226.          headView.setPadding(0, tempY - startY - headContentHeight,  
    227.            00);  
    228.          headView.invalidate();  
    229.         }  
    230.        }  
    231.        break;  
    232.       }  
    233.       return super.onTouchEvent(event);  
    234.      }  
    235.        
    236.      // 当状态改变时候,调用该方法,以更新界面  
    237.      private void changeHeaderViewByState() {  
    238.       switch (state) {  
    239.       case RELEASE_To_REFRESH:  
    240.        arrowImageView.setVisibility(View.VISIBLE);  
    241.        progressBar.setVisibility(View.GONE);  
    242.        tipsTextview.setVisibility(View.VISIBLE);  
    243.        lastUpdatedTextView.setVisibility(View.VISIBLE);  
    244.   
    245.        arrowImageView.clearAnimation();  
    246.        arrowImageView.startAnimation(animation);  
    247.   
    248.        tipsTextview.setText("松开刷新");  
    249.   
    250.        Log.v(TAG, "当前状态,松开刷新");  
    251.        break;  
    252.       case PULL_To_REFRESH:  
    253.        progressBar.setVisibility(View.GONE);  
    254.        tipsTextview.setVisibility(View.VISIBLE);  
    255.        lastUpdatedTextView.setVisibility(View.VISIBLE);  
    256.        arrowImageView.clearAnimation();  
    257.        arrowImageView.setVisibility(View.VISIBLE);  
    258.        // 是由RELEASE_To_REFRESH状态转变来的  
    259.        if (isBack) {  
    260.         isBack = false;  
    261.         arrowImageView.clearAnimation();  
    262.         arrowImageView.startAnimation(reverseAnimation);  
    263.   
    264.         tipsTextview.setText("下拉刷新");  
    265.        } else {  
    266.         tipsTextview.setText("下拉刷新");  
    267.        }  
    268.        Log.v(TAG, "当前状态,下拉刷新");  
    269.        break;  
    270.   
    271.       case REFRESHING:  
    272.   
    273.        headView.setPadding(0000);  
    274.        headView.invalidate();  
    275.   
    276.        progressBar.setVisibility(View.VISIBLE);  
    277.        arrowImageView.clearAnimation();  
    278.        arrowImageView.setVisibility(View.GONE);  
    279.        tipsTextview.setText("正在刷新...");  
    280.        lastUpdatedTextView.setVisibility(View.VISIBLE);  
    281.   
    282.        Log.v(TAG, "当前状态,正在刷新...");  
    283.        break;  
    284.       case DONE:  
    285.        headView.setPadding(0, -1 * headContentHeight, 00);  
    286.        headView.invalidate();  
    287.   
    288.        progressBar.setVisibility(View.GONE);  
    289.        arrowImageView.clearAnimation();  
    290.        arrowImageView  
    291.          .setImageResource(R.drawable.ic_pulltorefresh_arrow);  
    292.        tipsTextview.setText("下拉刷新");  
    293.        lastUpdatedTextView.setVisibility(View.VISIBLE);  
    294.   
    295.        Log.v(TAG, "当前状态,done");  
    296.        break;  
    297.       }  
    298.      }  
    299.   
    300.      public void setonRefreshListener(OnRefreshListener refreshListener) {  
    301.       this.refreshListener = refreshListener;  
    302.      }  
    303.   
    304.      public interface OnRefreshListener {  
    305.       public void onRefresh();  
    306.      }  
    307.   
    308.      public void onRefreshComplete() {  
    309.       state = DONE;  
    310.       lastUpdatedTextView.setText("最近更新:" + new Date().toLocaleString());//刷新完成时,头部提醒的刷新日期  
    311.       changeHeaderViewByState();  
    312.      }  
    313.   
    314.      private void onRefresh() {  
    315.       if (refreshListener != null) {  
    316.        refreshListener.onRefresh();  
    317.       }  
    318.      }  
    319.   
    320.      //此方法直接照搬自网络上的一个下拉刷新的demo,此处是“估计”headView的width以及height  
    321.      private void measureView(View child) {  
    322.       ViewGroup.LayoutParams p = child.getLayoutParams();  
    323.       if (p == null) {  
    324.        p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,  
    325.          ViewGroup.LayoutParams.WRAP_CONTENT);  
    326.       }  
    327.       int childWidthSpec = ViewGroup.getChildMeasureSpec(00 + 0, p.width);  
    328.       int lpHeight = p.height;  
    329.       int childHeightSpec;  
    330.       if (lpHeight > 0) {  
    331.        childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight,  
    332.          MeasureSpec.EXACTLY);  
    333.       } else {  
    334.        childHeightSpec = MeasureSpec.makeMeasureSpec(0,  
    335.          MeasureSpec.UNSPECIFIED);  
    336.       }  
    337.       child.measure(childWidthSpec, childHeightSpec);  
    338.      }  
    339.     } 

     

    4.head.xml,拷进项目基本不需改:

     
    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <!-- ListView的头部 -->  
    3. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    4.     android:id="@+id/head_rootLayout"  
    5.     android:layout_width="fill_parent"  
    6.     android:layout_height="wrap_content" >  
    7.  <!-- 内容 -->  
    8.     <RelativeLayout  
    9.         xmlns:android="http://schemas.android.com/apk/res/android"  
    10.         android:id="@+id/head_contentLayout"  
    11.         android:layout_width="fill_parent"  
    12.         android:layout_height="wrap_content"  
    13.         android:paddingLeft="30dp" >  
    14.         <!-- 箭头图像、进度条 -->  
    15.         <FrameLayout  
    16.             android:layout_width="wrap_content"  
    17.             android:layout_height="wrap_content"  
    18.             android:layout_alignParentLeft="true"  
    19.             android:layout_centerVertical="true" >  
    20.             <!-- 箭头 -->  
    21.             <ImageView  
    22.                 android:id="@+id/head_arrowImageView"  
    23.                 android:layout_width="wrap_content"  
    24.                 android:layout_height="wrap_content"  
    25.                 android:layout_gravity="center"  
    26.                 android:src="@drawable/ic_pulltorefresh_arrow"   
    27.                 android:contentDescription="@string/app_name"/>  
    28.             <!-- 进度条 -->  
    29.             <ProgressBar  
    30.                 android:id="@+id/head_progressBar"  
    31.                 style="?android:attr/progressBarStyleSmall"  
    32.                 android:layout_width="wrap_content"  
    33.                 android:layout_height="wrap_content"  
    34.                 android:layout_gravity="center"  
    35.                 android:visibility="gone" />  
    36.         </FrameLayout>  
    37.         <!-- 提示、最近更新 -->  
    38.         <LinearLayout  
    39.             android:layout_width="wrap_content"  
    40.             android:layout_height="wrap_content"  
    41.             android:layout_centerHorizontal="true"  
    42.             android:gravity="center_horizontal"  
    43.             android:orientation="vertical" >  
    44.             <!-- 提示 -->  
    45.             <TextView  
    46.                 android:id="@+id/head_tipsTextView"  
    47.                 android:layout_width="wrap_content"  
    48.                 android:layout_height="wrap_content"  
    49.                 android:text="@string/pulltorefresh"  
    50.                 android:textColor="#ffffff"  
    51.                 android:textSize="20sp" />  
    52.             <!-- 最近更新 -->  
    53.             <TextView  
    54.                 android:id="@+id/head_lastUpdatedTextView"  
    55.                 android:layout_width="wrap_content"  
    56.                 android:layout_height="wrap_content"  
    57.                 android:text="@string/lastupdate"  
    58.                 android:textColor="#cc6600"  
    59.                 android:textSize="10sp" />  
    60.         </LinearLayout>  
    61.     </RelativeLayout>  
    62. </LinearLayout>  

     

     殊途同归,扩展借鉴其他下拉刷新方式:

    http://blog.csdn.net/nono_love_lilith/article/details/7100845
    http://blog.csdn.net/nono_love_lilith/article/details/7202651

  • 相关阅读:
    pat甲级 1155 Heap Paths (30 分)
    pat甲级 1152 Google Recruitment (20 分)
    蓝桥杯 基础练习 特殊回文数
    蓝桥杯 基础练习 十进制转十六进制
    蓝桥杯 基础练习 十六进制转十进制
    蓝桥杯 基础练习 十六进制转八进制
    51nod 1347 旋转字符串
    蓝桥杯 入门训练 圆的面积
    蓝桥杯 入门训练 Fibonacci数列
    链表相关
  • 原文地址:https://www.cnblogs.com/armyant/p/2436341.html
Copyright © 2011-2022 走看看