(二)用戶交互 2.14轉發觸摸事件 1.TouchDelegate很適合簡單的觸摸轉發,它指定任意的矩形區域來向小視圖轉發觸摸事件,其缺點是每個被轉發的事件都會轉發到代理視圖的中間位置 2.自定義觸摸轉發 在onTouch中改變event事件信息 2.15阻止觸摸竊賊 1. 調用requestDi ...
(二)用戶交互
2.14轉發觸摸事件
1.TouchDelegate很適合簡單的觸摸轉發,它指定任意的矩形區域來向小視圖轉發觸摸事件,其缺點是每個被轉發的事件都會轉發到代理視圖的中間位置
public class TouchDelegateLayout extends FrameLayout { public TouchDelegateLayout(Context context) { this(context, null); } public TouchDelegateLayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } public TouchDelegateLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context); } private CheckBox mCheckBox; private void init(Context context) { mCheckBox = new CheckBox(context); mCheckBox.setText("tap anywhere"); addView(mCheckBox, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER)); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { if (w != oldw || h != oldh) { Rect rect = new Rect(0, 0, w, h); TouchDelegate touchDelegate = new TouchDelegate(rect, mCheckBox); setTouchDelegate(touchDelegate); } } }
2.自定義觸摸轉發
在onTouch中改變event事件信息
@Override public boolean onTouch(View v, MotionEvent event) { event.setLocation(event.getX(),event.getY()/2); scrollView.dispatchTouchEvent(event); return true; }
2.15阻止觸摸竊賊
1. 調用requestDisallowTouchIntercept()方法,請求父控制項不要截獲當前的觸摸事件
2.16創建拖放視圖
拖1.使用DragShadowBuilder構造被拖動視圖的外觀
2.調用View.startDrag()開啟拖動
@Override public boolean onLongClick(View v) { View.DragShadowBuilder shadowBuilder=new View.DragShadowBuilder(v); v.startDrag(null, shadowBuilder, ((ImageView) v).getDrawable(),0); return true; }
放
3.通過OnDragListener.onDrag()監聽拖動的事件,可以自定義一個視圖實現listener介面,以下為核心代碼
@Override public boolean onDrag(View v, DragEvent event) { PropertyValuesHolder pvhX, pvhY; switch (event.getAction()) { case DragEvent.ACTION_DRAG_STARTED: pvhX = PropertyValuesHolder.ofFloat("scaleX", 0.5f); pvhY = PropertyValuesHolder.ofFloat("scaleY", 0.5f); ObjectAnimator.ofPropertyValuesHolder(this, pvhX, pvhY).start(); setImageDrawable(null); mDropped = false; break; case DragEvent.ACTION_DRAG_ENDED: if (!mDropped) { pvhX = PropertyValuesHolder.ofFloat("scaleX", 1f); pvhY = PropertyValuesHolder.ofFloat("scaleY", 1f); ObjectAnimator.ofPropertyValuesHolder(this, pvhX, pvhY).start(); mDropped = false; } break; case DragEvent.ACTION_DRAG_ENTERED: pvhX = PropertyValuesHolder.ofFloat("scaleX", 0.75f); pvhY = PropertyValuesHolder.ofFloat("scaleY", 0.75f); ObjectAnimator.ofPropertyValuesHolder(this, pvhX, pvhY).start(); break; case DragEvent.ACTION_DRAG_EXITED: pvhX = PropertyValuesHolder.ofFloat("scaleX", 0.5f); pvhY = PropertyValuesHolder.ofFloat("scaleY", 0.5f); ObjectAnimator.ofPropertyValuesHolder(this, pvhX, pvhY).start(); break; case DragEvent.ACTION_DROP: Keyframe frame0=Keyframe.ofFloat(0f,0.75f); Keyframe frame1=Keyframe.ofFloat(0.5f,0f); Keyframe frame2=Keyframe.ofFloat(1f,0.75f); pvhX = PropertyValuesHolder.ofKeyframe("scaleX", frame0,frame1,frame2); pvhY = PropertyValuesHolder.ofKeyframe("scaleY", frame0, frame1, frame2); ObjectAnimator.ofPropertyValuesHolder(this, pvhX, pvhY).start(); setImageDrawable((Drawable) event.getLocalState()); mDropped=true; break; default: return false; } return true; }
2.17構建導航Drawer
1.DrawerLayout只在Android支持庫中提供,關鍵點在於設置gravity的屬性
<?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <FrameLayout android:id="@+id/middle" android:layout_width="match_parent" android:layout_height="match_parent"/> <ListView android:id="@+id/left" android:layout_width="240dp" android:layout_height="match_parent" android:layout_gravity="left" android:background="#555"/> <LinearLayout android:id="@+id/right" android:layout_width="240dp" android:layout_height="match_parent" android:layout_gravity="right" android:orientation="vertical" android:background="#ccc"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="this is right"/> </LinearLayout> </android.support.v4.widget.DrawerLayout>
2.當DrawerLayout與ActionBar結合時,要使用ActionBarDrawerToggle
mToggle = new ActionBarDrawerToggle(this, mDrawerContainer, R.string.open, R.string.close) { @Override public void onDrawerOpened(View drawerView) { super.onDrawerOpened(drawerView); supportInvalidateOptionsMenu(); } @Override public void onDrawerStateChanged(int newState) { super.onDrawerStateChanged(newState); supportInvalidateOptionsMenu(); } @Override public void onDrawerClosed(View drawerView) { super.onDrawerClosed(drawerView); supportInvalidateOptionsMenu(); } };
3.與ToolBar結合時,和之前類似有兩個要點,一是主題的風格,二是調用setActionBar(toolbar)方法
2.18在視圖之間滑動
1.定義PagerAdapter實現界面的佈局,主要方法是instantiateItem()
public class ImagePagerAdapter extends PagerAdapter { private Context mContext; private static final int[] IMAGES = { android.R.drawable.ic_menu_camera, android.R.drawable.ic_menu_add, android.R.drawable.ic_menu_delete, android.R.drawable.ic_menu_share, android.R.drawable.ic_menu_edit }; private static final int[] COLORS = { Color.RED, Color.BLUE, Color.GREEN, Color.GRAY, Color.MAGENTA }; public ImagePagerAdapter(Context context) { super(); mContext = context; } @Override public int getCount() { return IMAGES.length; } @Override public float getPageWidth(int position) { return 0.333f; } @Override public boolean isViewFromObject(View view, Object object) { return (view == object); } @Override public Object instantiateItem(ViewGroup container, int position) { ImageView iv = new ImageView(mContext); iv.setImageResource(IMAGES[position]); iv.setBackgroundColor(COLORS[position]); container.addView(iv); return iv; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View) object); } }
2.將adaper與viewpager適配
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ImagePagerAdapter adapter=new ImagePagerAdapter(this); ViewPager viewPager=new ViewPager(this); viewPager.setAdapter(adapter); setContentView(viewPager); }
2.18使用選項卡導航
1在sample中有一個SlidingTabBasic SDK,首先要將其中的SlidingTabLayout和SlidingTabStrip複製到自己的項目中
2.接著通過TabsPagerAdapter進行內容的適配,核心方法依然是instantiateItem()
private static class TabsPagerAdapter extends PagerAdapter { private Context mContext; public TabsPagerAdapter(Context mContext) { this.mContext = mContext; } @Override public CharSequence getPageTitle(int position) { switch (position) { case 0: return "PRIMARY"; case 1: return "SECONDARY"; case 2: return "TERTIARY"; case 3: return "QUATERNARY"; case 4: return "QUINARY"; default: return ""; } } @Override public int getCount() { return 5; } @Override public Object instantiateItem(ViewGroup container, int position) { ImageView imageView = new ImageView(mContext); imageView.setScaleType(ImageView.ScaleType.CENTER); imageView.setImageResource(R.mipmap.ic_launcher); container.addView(imageView); return imageView; } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View) object); } }
3.最後在activity中調用即可
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_action_tabs); ViewPager pager = (ViewPager) findViewById(R.id.pager); SlidingTabLayout tabLayout = (SlidingTabLayout) findViewById(R.id.tabs); assert pager != null; pager.setAdapter(new TabsPagerAdapter(this)); assert tabLayout != null; tabLayout.setViewPager(pager); tabLayout.setCustomTabColorizer(new SlidingTabLayout.TabColorizer() { @Override public int getIndicatorColor(int position) { return Color.WHITE; } @Override public int getDividerColor(int position) { return 0; } }); }
4.Google自帶的sample種有很多牛逼的例子,等考完軟考,就把官方的文檔和那些API例子一個一個懟掉