• android 横向滚动屏幕实现(2)


    本案例主要是模仿android launcher 实现加载应用程序,横向滚动屏幕,点击启动应用,可以拟补Gridview不能横向滚动缺陷

    源码下载地址:点击打开链接


    效果图:





    项目目录:



    主要代码:


    package com.sample.launcher.home;
    
    import java.util.Collections;
    import java.util.List;
    
    import android.app.Activity;
    import android.app.SearchManager;
    import android.content.ActivityNotFoundException;
    import android.content.BroadcastReceiver;
    import android.content.ComponentName;
    import android.content.Context;
    import android.content.Intent;
    import android.content.IntentFilter;
    import android.content.pm.PackageManager;
    import android.content.pm.ResolveInfo;
    import android.graphics.Canvas;
    import android.graphics.ColorFilter;
    import android.graphics.drawable.Drawable;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.view.ViewGroup.LayoutParams;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.Window;
    import android.view.WindowManager;
    import android.widget.AdapterView;
    import android.widget.GridView;
    import android.widget.Toast;
    import android.widget.AdapterView.OnItemClickListener;
    
    public class LauncherHomeActivity extends Activity {
    	
    	private ScrollLayout mScrollLayout;
    	private static final float APP_PAGE_SIZE = 16.0f;
    	private Context mContext;
    	private PointView pv;
    	private final BroadcastReceiver mWallpaperReceiver = new WallpaperIntentReceiver();
    	private final BroadcastReceiver mApplicationsReceiver = new ApplicationsIntentReceiver();
    	private int PageCount;
    	private List<ResolveInfo> apps;
    	
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    		getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);
    		mContext = this;
    		setContentView(R.layout.main);
    		
    		loadApps();
    		bindApps();
    		registerIntentReceivers();
        }
        
    	private void loadApps() {
    		final PackageManager packageManager = getPackageManager();
    
            final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
            mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
            
            // get all apps 
            apps = packageManager.queryIntentActivities(mainIntent, 0);
            Collections.sort(apps, new ResolveInfo.DisplayNameComparator(packageManager));
            // the total pages
            PageCount = (int)Math.ceil(apps.size()/APP_PAGE_SIZE);
    	}
    	
    	private void bindApps(){
    		
    		pv=(PointView)findViewById(R.id.PointLayput);
    		mScrollLayout = (ScrollLayout)findViewById(R.id.LauncherLayout);
    		
            pv.setPageCount(PageCount);
            mScrollLayout.setPointView(pv);
            
            for (int i=0; i<PageCount; i++) {
            	GridView appPage = new GridView(this);
            	// get the "i" page data
            	appPage.setAdapter(new AppAdapter(this, apps, i));
            	appPage.setNumColumns(4);
            	appPage.setOnItemClickListener(listener);
            	
           // 	LayoutParams params=new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
            	mScrollLayout.addView(appPage);
            }
    	}
    	
    	 @Override
    	    public boolean onCreateOptionsMenu(Menu menu) {
    	        super.onCreateOptionsMenu(menu);
    
    	        menu.add(0, Menu.FIRST, 0, "Setting").setIntent(new Intent(android.provider.Settings.ACTION_SETTINGS));
    	        menu.add(0, Menu.FIRST+1, 0, "unstall Apps");
    	        menu.add(0, Menu.FIRST+2, 0, "Aboat Phone").setIntent(new Intent(android.provider.Settings.ACTION_DEVICE_INFO_SETTINGS));
    	        return true;
    	    }
    
    	    @Override
    	    public boolean onOptionsItemSelected(MenuItem item) {
    	        switch (item.getItemId()) {
    	            case Menu.FIRST+1: 
    	              Intent intent = new Intent("/");  
    		          ComponentName cm = new ComponentName("com.android.settings","com.android.settings.ManageApplications");  
    		          intent.setComponent(cm);  
    		          intent.setAction("android.intent.action.VIEW");
    		          startActivity(intent);
    	               return true;
    	        }
    
    	        return super.onOptionsItemSelected(item);
    	    }
    	 /**
         * Registers various intent receivers. The current implementation registers
         * only a wallpaper intent receiver to let other applications change the
         * wallpaper.
         */
        private void registerIntentReceivers() {
            IntentFilter filter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED);
            registerReceiver(mWallpaperReceiver, filter);
    
            filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
            filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
            filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
            filter.addDataScheme("package");
            registerReceiver(mApplicationsReceiver, filter);
        }
        
    	private OnItemClickListener listener = new OnItemClickListener() {
    
    		public void onItemClick(AdapterView<?> parent, View view, int position,
    				long id) {
    			
    			ResolveInfo appInfo = (ResolveInfo)parent.getItemAtPosition(position);
    			Intent mainIntent = mContext.getPackageManager()
    				.getLaunchIntentForPackage(appInfo.activityInfo.packageName);
    			mainIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    
    			try {
    				// launcher the package
    				mContext.startActivity(mainIntent);
    			} catch (ActivityNotFoundException noFound) {
    				Toast.makeText(mContext, "Package not found!", Toast.LENGTH_SHORT).show();
    			}
    		}
    	};
    	
    	 /**
         * Receives intents from other applications to change the wallpaper.
         */
        private class WallpaperIntentReceiver extends BroadcastReceiver {
            @Override
            public void onReceive(Context context, Intent intent) {
                getWindow().setBackgroundDrawable(new ClippedDrawable(getWallpaper()));
            }
        }
    
        /**
         * Receives notifications when applications are added/removed.
         */
        private class ApplicationsIntentReceiver extends BroadcastReceiver {
            @Override
            public void onReceive(Context context, Intent intent) {
            	loadApps();
        		bindApps();
            }
        }
    	
        /**
         * When a drawable is attached to a View, the View gives the Drawable its dimensions
         * by calling Drawable.setBounds(). In this application, the View that draws the
         * wallpaper has the same size as the screen. However, the wallpaper might be larger
         * that the screen which means it will be automatically stretched. Because stretching
         * a bitmap while drawing it is very expensive, we use a ClippedDrawable instead.
         * This drawable simply draws another wallpaper but makes sure it is not stretched
         * by always giving it its intrinsic dimensions. If the wallpaper is larger than the
         * screen, it will simply get clipped but it won't impact performance.
         */
        private class ClippedDrawable extends Drawable {
            private final Drawable mWallpaper;
    
            public ClippedDrawable(Drawable wallpaper) {
                mWallpaper = wallpaper;
            }
    
            @Override
            public void setBounds(int left, int top, int right, int bottom) {
                super.setBounds(left, top, right, bottom);
                // Ensure the wallpaper is as large as it really is, to avoid stretching it
                // at drawing time
                mWallpaper.setBounds(left, top, left + mWallpaper.getIntrinsicWidth(),
                        top + mWallpaper.getIntrinsicHeight());
            }
    
            public void draw(Canvas canvas) {
                mWallpaper.draw(canvas);
            }
    
            public void setAlpha(int alpha) {
                mWallpaper.setAlpha(alpha);
            }
    
            public void setColorFilter(ColorFilter cf) {
                mWallpaper.setColorFilter(cf);
            }
    
            public int getOpacity() {
                return mWallpaper.getOpacity();
            }
        }
        
        @Override
        protected void onDestroy() {
        	 unregisterReceiver(mWallpaperReceiver);
             unregisterReceiver(mApplicationsReceiver);
        	super.onDestroy();
        }
        
    }

    package com.sample.launcher.home;
    
    import android.app.WallpaperManager;
    import android.content.Context;
    import android.os.IBinder;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.MotionEvent;
    import android.view.VelocityTracker;
    import android.view.View;
    import android.view.ViewConfiguration;
    import android.view.ViewGroup;
    import android.widget.Scroller;
    
    /**
     * 模仿launcher对手势进行分析处理,以及分屏显示,移动壁纸操作
     * @author Andy
     *
     */
    public class ScrollLayout extends ViewGroup {
    
    	private static final String TAG = "ScrollLayout";
    	private Scroller mScroller;
    	private VelocityTracker mVelocityTracker;
    	
    	private int mCurScreen;
    	private int mDefaultScreen = 0;
    	
    	private static final int TOUCH_STATE_REST = 0;
    	private static final int TOUCH_STATE_SCROLLING = 1;
    	
    	private static final int SNAP_VELOCITY = 600;
    	
    	private int mTouchState = TOUCH_STATE_REST;
    	private int mTouchSlop;
    	private float mLastMotionX;
    	private float mLastMotionY;
    	private WallpaperManager mWallpaperManager; 
    	PointView pv;
    	int lastScreen;
    
    	public ScrollLayout(Context context, AttributeSet attrs) {
    		this(context, attrs, 0);
    		
    	}
    
    	public ScrollLayout(Context context, AttributeSet attrs, int defStyle) {
    		super(context, attrs, defStyle);
    		
    		mWallpaperManager = WallpaperManager.getInstance(context);  
    		mScroller = new Scroller(context);
    		
    		mCurScreen = mDefaultScreen;
    		mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
    	}
    
    	public void setPointView(PointView pv){
    		this.pv=pv;
    	}
    	
    	@Override
    	protected void onLayout(boolean changed, int l, int t, int r, int b) {
    		Log.e(TAG, "onLayout");
    	//	if (changed) {
    			int childLeft = 0;
    			final int childCount = getChildCount();
    			
    			for (int i=0; i<childCount; i++) {
    				final View childView = getChildAt(i);
    				if (childView.getVisibility() != View.GONE) {
    					final int childWidth = childView.getMeasuredWidth();
    					childView.layout(childLeft, 0, 
    							childLeft+childWidth, childView.getMeasuredHeight());
    					childLeft += childWidth;
    				}
    			}
    	//	}
    		updateWallpaperOffset();  
    	}
    
    
        @Override  
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {   
        	Log.e(TAG, "onMeasure");
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);   
      
            final int width = MeasureSpec.getSize(widthMeasureSpec);   
            final int widthMode = MeasureSpec.getMode(widthMeasureSpec);   
            if (widthMode != MeasureSpec.EXACTLY) {   
                throw new IllegalStateException("ScrollLayout only canmCurScreen run at EXACTLY mode!"); 
            }   
      
            final int heightMode = MeasureSpec.getMode(heightMeasureSpec);   
            if (heightMode != MeasureSpec.EXACTLY) {   
                throw new IllegalStateException("ScrollLayout only can run at EXACTLY mode!");
            }   
      
            // The children are given the same width and height as the scrollLayout   
            final int count = getChildCount();   
            for (int i = 0; i < count; i++) {   
                getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);   
            }   
            // Log.e(TAG, "moving to screen "+mCurScreen);   
            scrollTo(mCurScreen * width, 0);         
        }  
        
        /**
         * According to the position of current layout
         * scroll to the destination page.
         */
        public void snapToDestination() {
        	final int screenWidth = getWidth();
        	final int destScreen = (getScrollX()+ screenWidth/2)/screenWidth;
        	snapToScreen(destScreen);
        }
        
        public void snapToScreen(int whichScreen) {
        	// get the valid layout page
        	whichScreen = Math.max(0, Math.min(whichScreen, getChildCount()-1));
        	if (getScrollX() != (whichScreen*getWidth())) {
        		
        		final int delta = whichScreen*getWidth()-getScrollX();
        		mScroller.startScroll(getScrollX(), 0, 
        				delta, 0, Math.abs(delta)*2);
        		mCurScreen = whichScreen;
        		invalidate();		// Redraw the layout
        	}
        }
        
        public void setToScreen(int whichScreen) {
        	whichScreen = Math.max(0, Math.min(whichScreen, getChildCount()-1));
        	mCurScreen = whichScreen;
        	scrollTo(whichScreen*getWidth(), 0);
        }
        
        public int getCurScreen() {
        	return mCurScreen;
        }
        
    	@Override
    	public void computeScroll() {
    		
    		if (mScroller.computeScrollOffset()) {
    			scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
    			updateWallpaperOffset();  
    			postInvalidate();
    		}
    	}
    
    	@Override
    	public boolean onTouchEvent(MotionEvent event) {
    		
    		if (mVelocityTracker == null) {
    			mVelocityTracker = VelocityTracker.obtain();
    		}
    		mVelocityTracker.addMovement(event);
    		
    		final int action = event.getAction();
    		final float x = event.getX();
    		lastScreen=mCurScreen;
    		
    		switch (action) {
    		case MotionEvent.ACTION_DOWN:
    			Log.e(TAG, "event down!");
    			if (!mScroller.isFinished()){
    				mScroller.abortAnimation();
    			}
    			mLastMotionX = x;
    			break;
    			
    		case MotionEvent.ACTION_MOVE:
    			int deltaX = (int)(mLastMotionX - x);
    			mLastMotionX = x;
    			
                scrollBy(deltaX, 0);
                updateWallpaperOffset();  
    			break;
    			
    		case MotionEvent.ACTION_UP:
    			Log.e(TAG, "event : up");   
                // if (mTouchState == TOUCH_STATE_SCROLLING) {   
                final VelocityTracker velocityTracker = mVelocityTracker;   
                velocityTracker.computeCurrentVelocity(1000);   
                int velocityX = (int) velocityTracker.getXVelocity();   
    
    //            Log.e(TAG, "velocityX:"+velocityX); 
                
                if (velocityX > SNAP_VELOCITY && mCurScreen > 0) {   
                    // Fling enough to move left   
                	Log.e(TAG, "snap left");
                    snapToScreen(mCurScreen - 1);
                } else if (velocityX < -SNAP_VELOCITY   
                        && mCurScreen < getChildCount() - 1) {   
                    // Fling enough to move right   
                	Log.e(TAG, "snap right");
                    snapToScreen(mCurScreen + 1);
                } else {   
                    snapToDestination();   
                }   
                
                if (mVelocityTracker != null) {   
                    mVelocityTracker.recycle();   
                    mVelocityTracker = null;   
                }   
                // }   
                mTouchState = TOUCH_STATE_REST;  
                
                if(mCurScreen>lastScreen){
    				pv.fromRighttoLeft();
    			}
    			else if(mCurScreen<lastScreen){
    				pv.fromLefttoRight();
    			}
    			break;
    		case MotionEvent.ACTION_CANCEL:
    			mTouchState = TOUCH_STATE_REST;
    			break;
    		}
    		
    		return true;
    	}
    
    	@Override
    	public boolean onInterceptTouchEvent(MotionEvent ev) {
    		
    //		Log.e(TAG, "onInterceptTouchEvent-slop:"+mTouchSlop);
    		
    		final int action = ev.getAction();
    		if ((action == MotionEvent.ACTION_MOVE) && 
    				(mTouchState != TOUCH_STATE_REST)) {
    			return true;
    		}
    		
    		final float x = ev.getX();
    		final float y = ev.getY();
    		
    		switch (action) {
    		case MotionEvent.ACTION_MOVE:
    			final int xDiff = (int)Math.abs(mLastMotionX-x);
    			if (xDiff>mTouchSlop) {
    				mTouchState = TOUCH_STATE_SCROLLING;
    				
    			}
    			break;
    			
    		case MotionEvent.ACTION_DOWN:
    			mLastMotionX = x;
    			mLastMotionY = y;
    			mTouchState = mScroller.isFinished()? TOUCH_STATE_REST : TOUCH_STATE_SCROLLING;
    			break;
    			
    		case MotionEvent.ACTION_CANCEL:
    		case MotionEvent.ACTION_UP:
    			mTouchState = TOUCH_STATE_REST;
    			break;
    		}
    		
    		return mTouchState != TOUCH_STATE_REST;
    	}
    	
    	 private void updateWallpaperOffset() {  
    	        int scrollRange = getChildAt(getChildCount() - 1).getRight() - getWidth();  
    	        IBinder token = getWindowToken();  
    	        if (token != null) {  
    	            mWallpaperManager.setWallpaperOffsetSteps(1.0f / (getChildCount() - 1), 0 );  
    	            mWallpaperManager.setWallpaperOffsets(getWindowToken(),  
    	                    Math.max(0.f, Math.min(getScrollX()/(float)scrollRange, 1.f)), 0);  
    	        }  
    	    }  
    
    }
    


    package com.sample.launcher.home;
    
    
    import java.security.acl.LastOwnerException;
    import java.util.ArrayList;
    import java.util.List;
    
    import android.content.Context;
    import android.database.Cursor;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.net.Uri;
    import android.os.Handler;
    import android.os.Message;
    import android.provider.MediaStore;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.widget.FrameLayout;
    import android.widget.ImageView;
    import android.widget.LinearLayout;
    import android.widget.RelativeLayout;
    import android.widget.ViewFlipper;
    import android.widget.FrameLayout.LayoutParams;
    import android.view.GestureDetector;
    import android.view.Gravity;
    import android.view.MotionEvent;
    import android.view.GestureDetector.OnGestureListener;
    import android.view.View;
    import android.view.View.OnTouchListener;
    import android.view.animation.Animation;
    import android.view.animation.TranslateAnimation;
    
    public class PointView extends FrameLayout{
    
    //	private int width,height;
    	private int index=0,PageCount=0;
    	private Context mContext;
    	
    	private Bitmap NormalPoint,SelectPoint;
    	private LinearLayout layout;
    	private ImageView lastsel,currentsel;
    //	private ImageView[] points=new ImageView[15];
    	
    	public PointView(Context context, AttributeSet attrs) {
    		super(context, attrs);
    		setView();
    	}
    
    	public PointView(Context c) {
    		super(c);
    		setView();
    	}
    	
    	public void setPageCount(int PageCount) {
    		this.PageCount = PageCount;
    		if(layout==null)
    			layout=(LinearLayout)findViewById(R.id.ContainerLayput);
    		
    		for (int j = 0; j < PageCount; j++) {
    			ImageView p=(ImageView)findViewById(R.id.point1+j);
    			p.setVisibility(View.VISIBLE);
    			if (j == 0) {
    				p.setImageBitmap(SelectPoint);
    			} else {
    				p.setImageBitmap(NormalPoint);
    			}
    		}
    		/*// 将点点动态加入Linerlayout.
    		for (int j = 0; j < PageCount; j++) {
    			ImageView imageview = new ImageView(mContext);
    			if (j == 0) {
    				imageview.setImageBitmap(SelectPoint);
    			} else {
    				imageview.setImageBitmap(NormalPoint);
    			}
    			RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
    					LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    			
    			layout.addView(imageview, params);
    		}
    		addView(layout);*/
    	}
    	
    	private void setView(){
    			
    		mContext = getContext();		
    	/*//	width = getResources().getDisplayMetrics().widthPixels;
    		layout = new LinearLayout(mContext);
    		layout.setGravity(Gravity.CENTER_HORIZONTAL);//Gravity.BOTTOM|*/
    		
    		NormalPoint= BitmapFactory.decodeResource(getResources(), R.drawable.page_off);
    		SelectPoint = BitmapFactory.decodeResource(getResources(), R.drawable.page_on);
    		
    	}
    
    	private boolean IsLeftEnable=false;
    	private boolean IsRightEnable=true;
    	
    	private void isEnd(){	Log.d("msg", "index= "+index);
    	
    		if(index<=0){
    			IsRightEnable=true;
    			IsLeftEnable=false;
    		}else if(index>=PageCount-1){
    			IsRightEnable=false;
    			IsLeftEnable=true;
    		}
    		// Log.d("msg", "IsRightEnable= "+IsRightEnable+" IsLeftEnable "+IsLeftEnable);
    	}
    	
    	public void fromLefttoRight() {
    		isEnd();
    		if (IsLeftEnable){
    			lastAnim();
    			index--;
    			nextAnim();
    		}
    	}
    
    	public void fromRighttoLeft() {
    		isEnd();
    		if (IsRightEnable){
    			lastAnim();
    			index++;
    			nextAnim();
    		}
    	}
    
    	private void lastAnim() {
    		// Log.e("msg", "layout= "+layout);
    		lastsel = (ImageView) layout.getChildAt(index);
    	}
    
    	private void nextAnim() {
    		// Log.e("msg", "curindex"+index);
    		currentsel = (ImageView) layout.getChildAt(index);
    		currentsel.setImageBitmap(SelectPoint);
    		lastsel.setImageBitmap(NormalPoint);
    	}
    
    }
    















  • 相关阅读:
    [极客大挑战 2019]EasySQL
    BUUCTF-[强网杯 2019]随便注-wp
    BUUCTF-[HCTF 2018]WarmUp-wp
    wp-2017ssrfme
    < 算法笔记(晴神宝典)
    < python音频库:Windows下pydub安装配置、过程出现的问题及常用API >
    < JAVA
    < 博客园自定义皮肤装饰代码
    <编译原理
    < AlexNet
  • 原文地址:https://www.cnblogs.com/happyxiaoyu02/p/6818959.html
Copyright © 2020-2023  润新知