照片墙的实现,是需要往手机里面添加很多图片的,如果没有对资源进行合理的释放,程序很快就会出现OOM.所以需要用到LruCache算法来缓存图片.


1,首先是图片资源类,这个类中包含了很多图片链接.
public class AllImages {
    public final static String[] imageUrls = new String[] {
            "http://img.my.csdn.net/uploads/201309/01/1378037235_3453.jpg",
            "http://img.my.csdn.net/uploads/201309/01/1378037235_7476.jpg",
            "http://img.my.csdn.net/uploads/201309/01/1378037235_9280.jpg",
            "http://img.my.csdn.net/uploads/201309/01/1378037234_3539.jpg",
            "http://img.my.csdn.net/uploads/201309/01/1378037234_6318.jpg",
            "http://img.my.csdn.net/uploads/201309/01/1378037194_2965.jpg",
            "http://img.my.csdn.net/uploads/201309/01/1378037193_1687.jpg",
            "http://img.my.csdn.net/uploads/201309/01/1378037193_1286.jpg",
            "http://img.my.csdn.net/uploads/201309/01/1378037192_8379.jpg",
            "http://img.my.csdn.net/uploads/201309/01/1378037178_9374.jpg",
            "http://img.my.csdn.net/uploads/201309/01/1378037177_1254.jpg",
            "http://img.my.csdn.net/uploads/201309/01/1378037177_6203.jpg",
            "http://img.my.csdn.net/uploads/201309/01/1378037152_6352.jpg",
            "http://img.my.csdn.net/uploads/201309/01/1378037151_9565.jpg",
            "http://img.my.csdn.net/uploads/201309/01/1378037151_7904.jpg",
            "http://img.my.csdn.net/uploads/201309/01/1378037148_7104.jpg",
            "http://img.my.csdn.net/uploads/201309/01/1378037129_8825.jpg",
            "http://img.my.csdn.net/uploads/201309/01/1378037128_5291.jpg",
            "http://img.my.csdn.net/uploads/201309/01/1378037128_3531.jpg",
            "http://img.my.csdn.net/uploads/201309/01/1378037127_1085.jpg",
            "http://img.my.csdn.net/uploads/201309/01/1378037095_7515.jpg",
            "http://img.my.csdn.net/uploads/201309/01/1378037094_8001.jpg",
            "http://img.my.csdn.net/uploads/201309/01/1378037093_7168.jpg",
            "http://img.my.csdn.net/uploads/201309/01/1378037091_4950.jpg",
            "http://img.my.csdn.net/uploads/201308/31/1377949643_6410.jpg",
            "http://img.my.csdn.net/uploads/201308/31/1377949642_6939.jpg",
            "http://img.my.csdn.net/uploads/201308/31/1377949630_4505.jpg",
            "http://img.my.csdn.net/uploads/201308/31/1377949630_4593.jpg",
            "http://img.my.csdn.net/uploads/201308/31/1377949629_7309.jpg",
            "http://img.my.csdn.net/uploads/201308/31/1377949629_8247.jpg",
            "http://img.my.csdn.net/uploads/201308/31/1377949615_1986.jpg",
            "http://img.my.csdn.net/uploads/201308/31/1377949614_8482.jpg",
            "http://img.my.csdn.net/uploads/201308/31/1377949614_3743.jpg",
            "http://img.my.csdn.net/uploads/201308/31/1377949614_4199.jpg",
            "http://img.my.csdn.net/uploads/201308/31/1377949599_3416.jpg",
            "http://img.my.csdn.net/uploads/201308/31/1377949599_5269.jpg",
            "http://img.my.csdn.net/uploads/201308/31/1377949598_7858.jpg",
            "http://img.my.csdn.net/uploads/201308/31/1377949598_9982.jpg",
            "http://img.my.csdn.net/uploads/201308/31/1377949578_2770.jpg",
            "http://img.my.csdn.net/uploads/201308/31/1377949578_8744.jpg",
            "http://img.my.csdn.net/uploads/201308/31/1377949577_5210.jpg",
            "http://img.my.csdn.net/uploads/201308/31/1377949577_1998.jpg",
            "http://img.my.csdn.net/uploads/201308/31/1377949482_8813.jpg",
            "http://img.my.csdn.net/uploads/201308/31/1377949481_6577.jpg",
            "http://img.my.csdn.net/uploads/201308/31/1377949480_4490.jpg",
            "http://img.my.csdn.net/uploads/201308/31/1377949455_6792.jpg",
            "http://img.my.csdn.net/uploads/201308/31/1377949455_6345.jpg",
            "http://img.my.csdn.net/uploads/201308/31/1377949442_4553.jpg",
            "http://img.my.csdn.net/uploads/201308/31/1377949441_8987.jpg",
            "http://img.my.csdn.net/uploads/201308/31/1377949441_5454.jpg",
            "http://img.my.csdn.net/uploads/201308/31/1377949454_6367.jpg",
            "http://img.my.csdn.net/uploads/201308/31/1377949442_4562.jpg" };
}
2.有了图片,还需要一个图片的工具类.新建一个ImageTools.
//图片处理的工具类
public class ImageTools {
    //图片缓存,用于缓存所有下载好的图片
    private static LruCache<String, Bitmap> mMemoryCache;
    
    //ImageTools实例
    private static ImageTools imageTools;
    
    public ImageTools() {
        //获取应用程序的最大可用内存
        int maxMemory=(int)Runtime.getRuntime().maxMemory();
        int cacheMemory=maxMemory/8;
        mMemoryCache=new LruCache<String, Bitmap>(cacheMemory){
            @Override
            protected int sizeOf(String key, Bitmap bitmap) {
                return bitmap.getByteCount();
            }
        };
    }
    //获取ImageTools的实例
    public static ImageTools getInstance(){
        if(imageTools==null){
            imageTools=new ImageTools();
        }
        return imageTools;
    }
    //将图片放入LruCache中
    public void addBitmapToMemoryCache(String key,Bitmap bitmap){
        if(getBitmapFromMemoryCache(key)==null){
            mMemoryCache.put(key, bitmap);
        }
    }
    //从LruCache中获取一张图片,如果不存在就返回null
    public Bitmap getBitmapFromMemoryCache(String key){
        return mMemoryCache.get(key);
    }
    //求出图片需要压缩的比例
    public static int calculateInSampleSize(BitmapFactory.Options option,int reqWidth){
        //得到原图片的宽度
        final int width=option.outWidth;
        int inSampleSize=1;
        if(width>reqWidth){
            //计算出实际宽度与目标宽度的比例
            final int widthRadio=Math.round((float)width/(float)reqWidth);
            inSampleSize=widthRadio;
        }
        return inSampleSize;
    }
    //压缩图片
    public static Bitmap decodeSampedBitmapFromResource(String pathName,int reqWidth){
        // 第一次解析将inJustDecodeBounds设置为true,来获取图片大小
        final BitmapFactory.Options options=new Options();
        options.inJustDecodeBounds=true;
        BitmapFactory.decodeFile(pathName, options);
        options.inSampleSize = calculateInSampleSize(options, reqWidth);
        // 使用获取到的inSampleSize值再次解析图片
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeFile(pathName, options);
    }
}
这里将ImageTools设为单例,并在构造函数中初始化了LruCache类,提供了操作LruCache的读取和增加方法  以及两个对图片进行处理的方法.
3.接下来就是最重要的MyScrollView类.核心类.
public class MyScrollView extends ScrollView  implements OnTouchListener {
    //每页要加载的图片数量
    public static final int PAGE_SIZE=15;
    //记录当前加载到了第几页
    private int page;
    //每一列的宽度
    private int columnWidth;
    //第一列的高度
    private int firstColumnHeight;
    //第二列的高度
    private int secondColumnHeight;
    //第三列的高度
    private int thirdColumnHeight;
    //是否已经加载过Layout
    private boolean loadOnce;
    //对图片进行管理的工具类
    private ImageTools imageTools;
    //第一列的布局
    private LinearLayout firstColumn;
    //第二列布局
    private LinearLayout secondColumn;
    //第三列布局
    private LinearLayout thirdColumn;
    //MyScrollView下的子布局
    private static View scrollLayout;
    //MyScrollView的高度
    private static int scrollViewHeight;
    //记录上次垂直滚动的距离
    private static int lastScrollY=-1;
    //记录界面上所有的图片
    private List<ImageView> imageList=new ArrayList<ImageView>();
    
    //记录所有正在下载的任务
    private static Set<LoadImageTask> imageTaskList;
    
    private static Handler mh=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            MyScrollView mScrollView=(MyScrollView) msg.obj;
            int scrollY=mScrollView.getScrollY();
            if(scrollY==lastScrollY){  //如果当前滚动位置与上次滚动位置相同,则说明滚动停止
                // 当滚动的最底部,并且当前没有正在下载的任务时,开始加载下一页的图片
                if(scrollViewHeight+scrollY>=scrollLayout.getHeight()&&imageTaskList.isEmpty()){
                    mScrollView.loadMoreImage();
                }
                mScrollView.checkVisiblility();
            }
            else{
                lastScrollY=scrollY;
                Message message = new Message();
                message.obj = mScrollView;
                // 5毫秒后再次对滚动位置进行判断
                mh.sendMessageDelayed(message, 5);
            }
        }
    };
    
    public MyScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
        imageTools=ImageTools.getInstance();
        imageTaskList=new HashSet<MyScrollView.LoadImageTask>();
        setOnTouchListener(this);
    }
    
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if(event.getAction()==MotionEvent.ACTION_UP){
            Message msg=new Message();
            msg.obj=this;
            mh.sendMessageDelayed(msg,5);
        }
        return false;
    }
    
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        if(changed&&!loadOnce){
            scrollViewHeight=getHeight();
            scrollLayout=getChildAt(0);
            firstColumn=(LinearLayout) findViewById(R.id.first_column);
            secondColumn=(LinearLayout) findViewById(R.id.second_column);
            thirdColumn=(LinearLayout) findViewById(R.id.third_column);
            columnWidth=firstColumn.getWidth();
            loadOnce=true;
            loadMoreImage();
        }
    }
    
    //加载更多图片
    public void loadMoreImage(){
        if(hasSDCard()){
            int startIndex=PAGE_SIZE*page;
            int endIndex=PAGE_SIZE*page+PAGE_SIZE;
            if(startIndex<AllImages.imageUrls.length){  //判断图片是否已经加载完毕
                Toast.makeText(getContext(), "正在加载",Toast.LENGTH_SHORT).show();
                if(endIndex>AllImages.imageUrls.length){
                    endIndex=AllImages.imageUrls.length;
                }
                for (int i = startIndex; i < endIndex; i++) {
                    LoadImageTask task=new LoadImageTask();
                    imageTaskList.add(task);
                    task.execute(AllImages.imageUrls[i]);
                }
                page++;
            }
            else{
                Toast.makeText(getContext(), "加载完毕",Toast.LENGTH_SHORT).show();
            }
        }
        else{
            Toast.makeText(getContext(), "没有内存卡",Toast.LENGTH_SHORT).show();
        }
    }
    
    //对图片的可见性进行检查,如果已经移出视线外,则将图片设为一张空白图片
    public void checkVisiblility(){
        for (int i = 0; i < imageList.size(); i++) {
            ImageView imageView=imageList.get(i);
            int border_top=(Integer) imageView.getTag(R.string.border_top);
            int border_bottom=(Integer) imageView.getTag(R.string.border_bottom);
            if(border_bottom>getScrollY()&&border_top<getScrollY()+scrollViewHeight){   //检查是不是在可见视图之内
                String imageUrl=(String) imageView.getTag(R.string.image_url);
                Bitmap imageBitmap=imageTools.getBitmapFromMemoryCache(imageUrl);
                if(imageBitmap==null){
                    LoadImageTask task=new LoadImageTask(imageView);
                    task.execute(imageUrl);
                }
                else{
                    imageView.setImageBitmap(imageBitmap);
                }
            }
            else{  //如果已经不再屏幕内
                imageView.setImageResource(R.drawable.ic_launcher);
            }
        }
    }
    
    //判断手机是否有SD卡
    private boolean hasSDCard(){
        return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());
    }
    
    //异步加载图片的任务
    class LoadImageTask extends AsyncTask<String, Void, Bitmap>{
        //图片地址Url
        private String imageUrl;
        //可重复使用的ImageView
        private ImageView mImageView;
        
        public LoadImageTask() {
            
        }
        //将可重复使用的ImageView传入
        public LoadImageTask(ImageView imageView) {
            this.mImageView=imageView;
        }
        
        @Override
        protected Bitmap doInBackground(String... params) { //根据imageUrl作为key值查找Bitmap,如果没有,调用loadImage去加载
            imageUrl=params[0];
            Bitmap imageBitmap=imageTools.getBitmapFromMemoryCache(imageUrl);
            if(imageBitmap==null){
                imageBitmap=loadImage(imageUrl);
            }
            return imageBitmap;
        }
        @Override
        protected void onPostExecute(Bitmap imageBitmap) {
            if(imageBitmap!=null){
                double ratio=imageBitmap.getWidth()/(columnWidth*1.0);   //得到宽度的压缩比
                int scaleHeight=(int)(imageBitmap.getHeight()/ratio);    //根据宽度的压缩比  得到这张图片的高度
                addImage(imageBitmap, columnWidth, scaleHeight);
            }
            imageTaskList.remove(this);
        }
        
        //根据图片的Url去加载图片   首先判断该图片是否在内存卡里面,如果没有,则去下载,如果有,则经过压缩处理后返回
        private Bitmap loadImage(String imageUrl){
            File imageFile=new File(getImagePath(imageUrl));
            if(!imageFile.exists()){
                downloadImage(imageUrl);
            }
            if(imageUrl!=null){
                Bitmap bitmap=ImageTools.decodeSampedBitmapFromResource(imageFile.getPath(), columnWidth);
                if(bitmap!=null){
                    imageTools.addBitmapToMemoryCache(imageUrl, bitmap);
                    return bitmap;
                }
            }
            return null;
        }
        
        
        //向ImageView中添加一张图片
        private void addImage(Bitmap bitmap,int imageWidth,int imageHeight){
            LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(imageWidth, imageHeight);
            if(mImageView!=null){
                mImageView.setImageBitmap(bitmap);
            }
            else{
                ImageView imageView=new ImageView(getContext());
                imageView.setLayoutParams(params);
                imageView.setImageBitmap(bitmap);
                imageView.setScaleType(ScaleType.FIT_XY);
                imageView.setPadding(5, 5, 5, 5);
                imageView.setTag(R.string.image_url,imageUrl);
                findColumnToAdd(imageView, imageHeight).addView(imageView);
                imageList.add(imageView);
                }
        }
        
        
        //找到应该添加图片的一列,选取三列中高度最小的一列返回.
        private LinearLayout findColumnToAdd(ImageView imageView,int imageHeight){
            if(firstColumnHeight<=secondColumnHeight){
                if(firstColumnHeight<=thirdColumnHeight){
                    imageView.setTag(R.string.border_top,firstColumnHeight);
                    firstColumnHeight+=imageHeight;
                    imageView.setTag(R.string.border_bottom,firstColumnHeight);
                    return firstColumn;
                }
                else{
                    imageView.setTag(R.string.border_top,thirdColumnHeight);
                    thirdColumnHeight+=imageHeight;
                    imageView.setTag(R.string.border_bottom,thirdColumnHeight);
                    return thirdColumn;
                }
            }
            else{
                if(secondColumnHeight<=thirdColumnHeight){
                    imageView.setTag(R.string.border_top,secondColumnHeight);
                    secondColumnHeight+=imageHeight;
                    imageView.setTag(R.string.border_bottom, secondColumnHeight);
                    return secondColumn;
                }
                else{
                    imageView.setTag(R.string.border_top,thirdColumnHeight);
                    thirdColumnHeight+=imageHeight;
                    imageView.setTag(R.string.border_bottom,thirdColumnHeight);
                    return thirdColumn;
                }
            }
        }
        
        //将图片下载到SD卡缓存
        private void downloadImage(String imageUrl){
            HttpURLConnection con=null;
            FileOutputStream fos=null;
            BufferedOutputStream bos=null;
            BufferedInputStream bis=null;
            File imageFile=null;
            try {
                URL url=new URL(imageUrl);
                con=(HttpURLConnection) url.openConnection();
                con.setConnectTimeout(5*1000);
                con.setReadTimeout(15*1000);
                con.setDoInput(true);
                con.setDoOutput(true);
                bis=new BufferedInputStream(con.getInputStream());
                imageFile =new File(getImagePath(imageUrl));//获得了图片的路径
                fos=new FileOutputStream(imageFile);
                bos=new BufferedOutputStream(fos);
                byte[] b=new byte[1024];
                int length;
                while((length=bis.read(b))!=-1){
                    bos.write(b, 0, length);
                    bos.flush();
                }
                
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            finally{
                    try {
                        if(bis!=null){
                            bis.close();
                        }
                        if(bos!=null){
                            bos.close();
                        }
                        if(con!=null){
                            con.disconnect();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
            }
            if(imageFile!=null){
                //裁剪图片
                Log.e("info", "path---"+imageFile.getPath());
                Bitmap bitmap=ImageTools.decodeSampedBitmapFromResource(imageFile.getPath(), columnWidth);
                if(bitmap!=null){
                    imageTools.addBitmapToMemoryCache(imageUrl, bitmap);
                }
            }
        }
        
    }
    //获取图片的本地缓存路径
    private String getImagePath(String imageUrl){
        int lastIndex=imageUrl.lastIndexOf("/");
        String imageName=imageUrl.substring(lastIndex+1);
        String imageDir=Environment.getExternalStorageDirectory().getPath()+"/PhotoWallFall/";
        File file=new File(imageDir);
        if(!file.exists()){
            file.mkdirs();
        }
        String imagePath=imageDir+imageName;
        return imagePath;
    }

}  

这个自定义控件是继承自ScrollView类的,这样就允许用户可以通过滚动的方式浏览更多的图片,loadMoreImage()是专门用来浏览下一页图片的.


看一看loadMoreImages()方法的内部细节了。在这个方法中,使用了一个循环来加载这一页中的每一张图片,每次都会开启一
个LoadImageTask,用于对图片进行异步加载。然后在LoadImageTask中,首先会先检查一下这张图片是不是已经存在于SD卡中了,如果还没
存在,就从网络上下载,然后把这张图片存放在LruCache中。接着将这张图按照一定的比例进行压缩,并找出当前高度最小的一列,把压缩
后的图片添加进去就可以了。
另外,为了保证照片墙上的图片都能够合适地被回收,这里还加入了一个可见性检查的方法,即checkVisibility()方法。这个方法的核心思
想就是检查目前照片墙上的所有图片,判断出哪些是可见的,哪些是不可见。然后将那些不可见的图片都替换成一张空图,这样就可以保证
程序始终不会占用过高的内存。当这些图片又重新变为可见的时候,只需要再从LruCache中将这些图片重新取出即可。如果某张图片已经从
LruCache中被移除了,就会开启一个LoadImageTask,将这张图片重新加载到内存中.

4.打开activity_main.xml
<com.example.photodemo.MyScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/scroll_view"
    tools:context=".MainActivity" >
    
    <LinearLayout 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        >
        <LinearLayout 
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:id="@+id/first_column"
            android:orientation="vertical"
            ></LinearLayout>
                <LinearLayout 
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:id="@+id/second_column"
            android:orientation="vertical"
            ></LinearLayout>
                        <LinearLayout 
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:id="@+id/third_column"
            android:orientation="vertical"
            ></LinearLayout>
        
    </LinearLayout>
</com.example.photodemo.MyScrollView>

5.当然,因为是获取网络图片,所以必须加上联网权限 ,以及将图片缓存到SD卡,所以需要写权限.
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<uses-permission android:name="android.permission.INTERNET" />

 


android瀑布流照片墙实现代码详解的更多相关文章

  1. Android瀑布流照片墙实现,体验不规则排列的美感

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/10470797 传统界面的布局方式总是行列分明.坐落有序的,这种布局已是司空见惯,在 ...

  2. 转载—— android 瀑布流的实现详解,附源码

    介绍 参考自:https://github.com/dodola/android_waterfall,因为原来的代码封装不好,所以,我根据源码的思路,重新写了一遍,所以有了现在这个项目:https:/ ...

  3. [JS练习] 瀑布流照片墙

    记录JS实现瀑布流照片墙效果 首先是前端页面 <!DOCTYPE html> <html lang="en"> <head> <meta ...

  4. Android EventBus 3.0 实例使用详解

    EventBus的使用和原理在网上有很多的博客了,其中泓洋大哥和启舰写的非常非常棒,我也是跟着他们的博客学会的EventBus,因为是第一次接触并使用EventBus,所以我写的更多是如何使用,源码解 ...

  5. Android开发:文本控件详解——TextView(一)基本属性

    一.简单实例: 新建的Android项目初始自带的Hello World!其实就是一个TextView. 在activity_main.xml中可以新建TextView,从左侧组件里拖拽到右侧预览界面 ...

  6. [置顶] xamarin android toolbar(踩坑完全入门详解)

    网上关于toolbar的教程有很多,很多新手,在使用toolbar的时候踩坑实在太多了,不好好总结一下,实在浪费.如果你想学习toolbar,你肯定会去去搜索androd toolbar,既然你能看到 ...

  7. Android瀑布流照片

    http://blog.csdn.net/guolin_blog/article/details/10470797 记得我在之前已经写过一篇关于如何在Android上实现照片墙功能的文章了,但那个时候 ...

  8. Android 多线程之IntentService 完全详解

    关联文章: Android 多线程之HandlerThread 完全详解 Android 多线程之IntentService 完全详解 android多线程-AsyncTask之工作原理深入解析(上) ...

  9. Android 多线程之HandlerThread 完全详解

    关联文章: Android 多线程之HandlerThread 完全详解 Android 多线程之IntentService 完全详解 android多线程-AsyncTask之工作原理深入解析(上) ...

随机推荐

  1. Redis 命令学习

    每天不学习点新的东西,感觉就有点会被社会淘汰掉了.也许现在学习的知识会很快忘记,下次学习用到这个知识点的时候,再回来翻记录的笔记,我想这样会比从头再学,效率会高点吧. 闲话不多聊,回归正题.今天学习r ...

  2. Ajax的学习笔记(一)

    AJAX即“Asynchronous Javascript And XML”(异步JavaScript和XML),ajax并不是一门单独的语言,而是一种技术,是指一种创建交互式网页应用的网页开发技术. ...

  3. 旧文备份:对象字典0x1005和0x1006的理解

    SYNC不一定由主站产生,因此,产生SYNC的节点,0x1005对象的值一般是0x40000080,第30位为1表示本节点产生 SYNC,而本节点的0x1006对象就是产生同步周期值了;而接收SYNC ...

  4. java 基础词汇 必须 第九天

    Collection 集合 List 列表集合 Set 不重复集合 Linked 链表 Vector 线程安全集合 Hash 哈希值 tree 树型结构 Map 键值对集合 add 增加 remove ...

  5. C编程经验总结

    Turbo c Return (z);=return z; 图形界面的有scanf(“%d ~%d\n”,&~,&~);注意:中间不能有乱的东西 Printf(“~~~ %d~~%d\ ...

  6. ABAP调用WebService时日期类型问题

    在使用ABAP调用WebService时, 提示CX_SY_CONVERSION_NO_DATE_TIME,意思是日期格式不能转化. 究其原因是ABAP里没有相应的数据类型与WebService描述里 ...

  7. BeanUtils工具的实现

    BeanUtils工具的实现 自定义一个将数据映射到类里的方法 方法一: package utils; import java.lang.reflect.Field; import java.lang ...

  8. PHP常用180函数总结

    数学函数 1.abs(): 求绝对值 <span style="font-size: 14px;">$abs = abs(-4.2); //4.2<br>& ...

  9. 用ajax获取淘宝关键字接口

    可定需要查看淘宝界面的结构,按F12查看网页,此时先清除一下网页中的数据,让Network制空,随后在输入框中输入新的内容,比如钱包,数据中会出现新的数据.点击及查看蓝色方框中的内容 点击之后,你可以 ...

  10. A Country on Wheels【车轮上的国家】

    A Country on Wheels As cultural symbols go, the American  car is quite young. 作为文化象征的美国汽车还相当年轻. The ...