天天看點

OTT界面開發中焦點移動框和擷取焦點後圖檔變化效果實作

OTT界面開發中焦點移動框和擷取焦點後圖檔變化效果實作

OTT開發和手機開發最大的差別是,手機以觸摸點選事件為主,而OTT大部分操作是通過遙控器,是以呈現給使用者的大部分是焦點切換事件,即onfocuschange監聽事件

OTT界面開發中焦點移動框和擷取焦點後圖檔變化效果實作

整體launcher布局是首頁中加入四個fragment互相切換

首頁activity:MainActivity代碼如下

public class MainActivity extends FragmentActivity
{
	private static final String TAG = "MainActivity";
	private ViewPager mViewPager;
	private FragmentPagerAdapter mAdapter;
	private List<Fragment> mFragments = new ArrayList<Fragment>();

	private Button mTabBtnLive;
	private Button mTabBtnHD;
	private Button mTabBtnLookback;
	private Button mTabBtnApplication;
	
	//整體布局
	private LinearLayout mainLayout;

	// headbar上的下劃線
	private ImageView headbar_underline;
	// headbar下劃線上一次位置所在
	private static int headbar_underline_lastPos = 0;

	// 視訊坑位尺寸
	public static int extra_button_width;
	public static int extra_button_height;

	// 當tab的index
	public static int currentIndex = 0;

	// 總頁數
	public static final int PAGE_NUM = 4;

	// 應用操作
	private ApplicationOperation applicationOperation;
	public static RelativeLayout main_bottom;
	private LinearLayout tips;
	private String preContentDes;

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		initView();

		mAdapter = new TabAdapter(getSupportFragmentManager());
		mViewPager.setOffscreenPageLimit(PAGE_NUM);
		mViewPager.setAdapter(mAdapter);
		mViewPager.setOnPageChangeListener(new TabChangeLis());
	}

	@Override
	protected void onResume()
	{
		super.onResume();
	}

	@Override
	protected void onPause()
	{
		super.onPause();
	}
	
	@Override
	protected void onDestroy()
	{
		super.onDestroy();
	}

	/**
	 *  head bar上的tab按鈕焦點效果清除
	 * */
	protected void defocusTabBtn()
	{
		mTabBtnLive.setTextColor(getResources().getColor(R.color.white_50));
		mTabBtnHD.setTextColor(getResources().getColor(R.color.white_50));
		mTabBtnLookback.setTextColor(getResources().getColor(R.color.white_50));
		mTabBtnApplication.setTextColor(getResources().getColor(R.color.white_50));
	}

	/**
	 *初始化工作
	 * */
	private void initView()
	{
		mainLayout = (LinearLayout) findViewById(R.id.mainLayout);
		
		mViewPager = (ViewPager) findViewById(R.id.id_viewpager);


		// tab按鈕初始化
		mTabBtnLive = (Button) findViewById(R.id.tab_btn_recommend);
		mTabBtnHD = (Button) findViewById(R.id.tab_btn_movie);
		mTabBtnLookback = (Button) findViewById(R.id.tab_btn_game);
		mTabBtnApplication = (Button) findViewById(R.id.tab_btn_child);

		// 各個分界面, 按順序添加
		mFragments.add(new MainTabLive(getApplicationContext()));
		mFragments.add(new MainTabLookback(getApplicationContext()));
		mFragments.add(new MainTabHD(getApplicationContext()));
		mFragments.add(new MainTabApplication(getApplicationContext()));

		// tab按鈕添加監聽
		TabBtnFocLis tabBtnFocLis = new TabBtnFocLis();
		mTabBtnLive.setOnFocusChangeListener(tabBtnFocLis);
		mTabBtnHD.setOnFocusChangeListener(tabBtnFocLis);
		mTabBtnLookback.setOnFocusChangeListener(tabBtnFocLis);
		mTabBtnApplication.setOnFocusChangeListener(tabBtnFocLis);

		// headbar下劃線
		headbar_underline = (ImageView) findViewById(R.id.headbar_underline);

		extra_button_width = (int) getResources().getDimension(
				R.dimen.extra_button_width);
		extra_button_height = (int) getResources().getDimension(
				R.dimen.extra_button_height);

		// 底部視圖
		main_bottom = (RelativeLayout) findViewById(R.id.main_bottom);
		tips = (LinearLayout) findViewById(R.id.tips);
		mViewPager.setCurrentItem(0);
	}

	/**
	 * 擷取tab内容頁的順序
	 * */
	public int getTabOrder(View v)
	{
		switch (v.getId())
		{
		case R.id.tab_btn_recommend:
			return 0;
		case R.id.tab_btn_movie:
			return 1;
		case R.id.tab_btn_game:
			return 2;
		case R.id.tab_btn_child:
			return 3;
		default:
			return 0;
		}
	}



	class TabChangeLis implements OnPageChangeListener
	{
		@Override
		public void onPageSelected(int position)
		{
			defocusTabBtn();

			// 顯示推薦頁下面的下拉提示箭頭按鈕
			if (position == 0)
			{
				main_bottom.setVisibility(View.VISIBLE);
			}
			else
			{
				main_bottom.setVisibility(View.INVISIBLE);
			}

			switch (position)
			{
			case 0:
				mTabBtnLive.setTextColor(getResources().getColor(
						R.color.white));
				break;
			case 1:
				mTabBtnHD.setTextColor(getResources()
						.getColor(R.color.white));
				break;
			case 2:
				mTabBtnLookback
						.setTextColor(getResources().getColor(R.color.white));
				break;
			case 3:
				mTabBtnApplication.setTextColor(getResources()
						.getColor(R.color.white));
				break;
			}

			currentIndex = position;

			startLineAnimation(position);// 顯示headbar的下劃線效果
		}

		@Override
		public void onPageScrolled(int arg0, float arg1, int arg2)
		{
		}

		@Override
		public void onPageScrollStateChanged(int arg0)
		{
		}
	}

	class TabAdapter extends FragmentPagerAdapter
	{
		public TabAdapter(FragmentManager fm)
		{
			super(fm);
		}

		@Override
		public int getCount()
		{
			return mFragments.size();
		}

		@Override
		public Fragment getItem(int arg0)
		{
			return mFragments.get(arg0);
		}
	}

	/**
	 *  head bar上的tab按鈕焦點狀态變化監聽
	 * */
	class TabBtnFocLis implements OnFocusChangeListener
	{
		@Override
		public void onFocusChange(View v, boolean hasFocus)
		{
			if (hasFocus)
			{
				headbar_underline
						.setBackgroundResource(R.drawable.headbar_focus_underline);

				mViewPager.setCurrentItem(getTabOrder(v));

				if (!v.hasFocus())
				{
					v.requestFocus();
				}
			}
			else
			{
				headbar_underline
						.setBackgroundResource(R.color.transparent_100);
			}
		}
	}
	
	/**
	 * 
	 * 調整HorizontalScrollView的位置
	 * */
	public void adjustScrollViewPos(HorizontalScrollView hScrollView, View currentFocus)
	{
		// 當焦點在tab标題切換時,tab下方的内容橫向坐标置為0
		if (hScrollView != null 
				&& currentFocus != null
				&& currentFocus.getContentDescription()!=null 
				&& currentFocus.getContentDescription().equals("headbar"))
		{
			hScrollView.scrollTo(0, 0);
		}
	}

	/**
	 * 
	 * headbar下劃線移動
	 * */
	private void startLineAnimation(int index)
	{
		if (index < 0 || index >= mFragments.size())
		{
			return;
		}

		int stepLength = ((int) getResources().getDimension(
				R.dimen.headbar_title_width))
				+ ((int) getResources().getDimension(
						R.dimen.headbar_divide_width));// 移動步長

		int underline_to_left = (int) getResources().getDimension(
				R.dimen.headbar_underline_to_left);

		Animation animation = null;
		animation = new TranslateAnimation(headbar_underline_lastPos,
				stepLength * index, 0, 0);// 下滑線動畫
		headbar_underline_lastPos = stepLength * index;

		animation.setFillAfter(true);
		animation.setDuration(300);
		headbar_underline.startAnimation(animation);
	}
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK )  
        { 
			return false;
        }
		return super.onKeyDown(keyCode, event);
	}
	
}
           

MainActivity的布局檔案

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/mainLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/wallpaper"
    android:orientation="vertical" >
    
    <include layout="@layout/status_bar" />
    
    <include layout="@layout/head_bar" />
    
    <android.support.v4.view.ViewPager
        android:id="@+id/id_viewpager"
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="1" >
    </android.support.v4.view.ViewPager>
    
    <include   layout="@layout/main_tip"/>
    <include layout="@layout/main_bottom" />    

</LinearLayout>
           
</pre><pre name="code" class="html">第一個fragment中的内容
           
public class MainTabLive extends Fragment implements OnClickListener
{
	private static final String TAG = "MainTabRecommend";
	
	private Context mContext;
	
	public static SurfaceView button1_1;
	public static Button button1_51;
	public static Button button1_52;
	public static Button button1_2;
	public static Button button1_3;
	public static Button button1_4;
	public static Button button1_5;
	public static Button button1_6;
	public static Button button1_7;
	public static Button button1_8;
	public static Button button1_9;
	public static Button button1_10;
	public static ImageView focus_img;
	public static Button message_spot;
	public static ImageView video_play_icon;
	public static Boolean isPlaying = false;
	public MediaPlayer mediaPlayer;
	private static MainTabLive mainTabLive = null;
	public AVPlayerManager aVPlayerManager = null;
	public ProgManager proManager = null;
	private static String curr_prog_num;// 目前台号
	public static int volume = 16;  //聲音初始值
	//目前fragment處于使用者可見狀态時的時間
	public static long visible_time = 0;
	//目前fragment處于使用者不可見狀态時的時間
	public static long invisible_time = 0;
	
	
	private HorizontalScrollView horizontalScrollView;
	
	public MainTabLive()
	{
	}
	
	public MainTabLive(Context context)
	{
		super();
		mContext = context;
	}
	
	/*public static MainTabLive getInstance(){
		return mainTabLive;
	}
	*/
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState)
	{
		View recommendLayout = inflater.inflate(R.layout.main_tab_live,
				container, false);

		initView(recommendLayout);
		return recommendLayout;
	}
	
	@Override
	public void onResume()
	{
		DVB.GetInstance().SetDVBStatus(1);
		aVPlayerManager.startPlayer();
		aVPlayerManager.setPlayerVolume(volume);
		aVPlayerManager.setPlayerWindow(50, 110, 470, 350);
		
		super.onResume();	
	}
	
	@Override
	public void onPause() {
		
		if(aVPlayerManager != null){
			aVPlayerManager.stopPlayer();
		}
		DVB.GetInstance().ReleaseResource();
		super.onPause();
		
	}
	@Override
	public void onStop() {	
    		
		super.onStop();
	}
	@Override
	public void onDestroy() {
		super.onDestroy();
	}
	
	/**
	 *  初始化視覺控件
	 * */
	public void initView(View view)
	{
		//horizontalScrollView = (HorizontalScrollView) view.findViewById(R.id.main_recommend);
		
		button1_1 = (SurfaceView) view.findViewById(R.id.button1_1);
		button1_2 = (Button) view.findViewById(R.id.button1_2);
		button1_3 = (Button) view.findViewById(R.id.button1_3);
		button1_51 = (Button) view.findViewById(R.id.button1_51);
		button1_52 = (Button) view.findViewById(R.id.button1_52);
		button1_4 = (Button) view.findViewById(R.id.button1_4);
		button1_5 = (Button) view.findViewById(R.id.button1_5);
		button1_6 = (Button) view.findViewById(R.id.button1_6);
		button1_7 = (Button) view.findViewById(R.id.button1_7);
		button1_8 = (Button) view.findViewById(R.id.button1_8);
		button1_9 = (Button) view.findViewById(R.id.button1_9);
		button1_10 = (Button) view.findViewById(R.id.button1_10);
		focus_img = (ImageView) view.findViewById(R.id.recommend_focus_img);
		video_play_icon = (ImageView) view.findViewById(R.id.video_play_icon);
		//video_pause_shadow = (Button) view.findViewById(R.id.video_pause_shadow);
		
		button1_2.setNextFocusUpId(R.id.tab_btn_recommend);
		button1_3.setNextFocusUpId(R.id.tab_btn_recommend);
		button1_4.setNextFocusUpId(R.id.tab_btn_recommend);
		button1_1.setNextFocusUpId(R.id.tab_btn_recommend);
		
		OnFocusChangeLis focusChangeListener = new OnFocusChangeLis();
		OnFocusChangeBig focusChangeBig = new OnFocusChangeBig();
		button1_1.setOnFocusChangeListener(focusChangeBig);
		button1_2.setOnFocusChangeListener(focusChangeListener);
		button1_3.setOnFocusChangeListener(focusChangeListener);
		button1_51.setOnFocusChangeListener(focusChangeListener);
		button1_52.setOnFocusChangeListener(focusChangeListener);
		button1_4.setOnFocusChangeListener(focusChangeListener);
		button1_5.setOnFocusChangeListener(focusChangeListener);
		button1_6.setOnFocusChangeListener(focusChangeListener);
		button1_7.setOnFocusChangeListener(focusChangeListener);
		button1_8.setOnFocusChangeListener(focusChangeListener);
		button1_9.setOnFocusChangeListener(focusChangeListener);
		button1_10.setOnFocusChangeListener(focusChangeListener);
		
		button1_1.setOnClickListener(this);
		button1_2.setOnClickListener(this);
		button1_3.setOnClickListener(this);
		button1_51.setOnClickListener(this);
		button1_52.setOnClickListener(this);
		button1_4.setOnClickListener(this);
		button1_5.setOnClickListener(this);
		button1_6.setOnClickListener(this);
		button1_7.setOnClickListener(this);
		button1_8.setOnClickListener(this);
		button1_9.setOnClickListener(this);
		button1_10.setOnClickListener(this);
		
		aVPlayerManager = AVPlayerManager.getInstance();
		proManager = ProgManager.getInstance();
		if(null !=  aVPlayerManager.getCurrProgShowInfoByMap())
		{
			curr_prog_num = aVPlayerManager.getCurrProgShowInfoByMap().get("PROG_NUM");
		}else{
			curr_prog_num = null;
		}
	}
	
	@Override
	public void onClick(View v) {
		String numId = null;
		if(null !=  aVPlayerManager.getCurrProgShowInfoByMap())
		{
			curr_prog_num = aVPlayerManager.getCurrProgShowInfoByMap().get("PROG_NUM");
		}else{
			curr_prog_num = null;
		}
		if(curr_prog_num!=null){
		switch (v.getId()) {
		case R.id.button1_1:
			gotoOutPakage(curr_prog_num);
			break;
		case R.id.button1_2:   //CCTV-1
			 numId = proManager.getProgNumByServiceid(4001);
			if(numId!=null){
			gotoOutPakage(numId);
			}
			break;
		case R.id.button1_3:  //CCTV-3
			// numId = proManager.getProgNumByServiceid(78);
			/*if(numId!=null){
			gotoOutPakage(numId);
			}*/
			break;
		case R.id.button1_4:	//CCTV-5
			numId = proManager.getProgNumByServiceid(4101);
			if(numId!=null){
			gotoOutPakage(numId);
			}
			break;
		case R.id.button1_5:	//CCTV-6
			//numId = proManager.getProgNumByServiceid(4001);
			/*if(numId!=null){
			gotoOutPakage(numId);
			}*/
			break;
		case R.id.button1_6:	//CCTV-9
			numId = proManager.getProgNumByServiceid(4102);
			if(numId!=null){
			gotoOutPakage(numId);
			}
			break;
		case R.id.button1_7:	//北京高清
			numId = proManager.getProgNumByServiceid(4201);
			if(numId!=null){
			gotoOutPakage(numId);
			}
			break;
		case R.id.button1_8:	//浙江高清
			numId = proManager.getProgNumByServiceid(4601);
			if(numId!=null){
			gotoOutPakage(numId);
			}
			break;
		case R.id.button1_9:	//江蘇高清
			numId = proManager.getProgNumByServiceid(4501);
			if(numId!=null){
			gotoOutPakage(numId);
			}
			break;
		case R.id.button1_10:	//湖南高清
			numId = proManager.getProgNumByServiceid(4401);
			if(numId!=null){
			gotoOutPakage(numId);
			}
			break;
		default:
			break;
		}
		}
	}
	private void gotoOutPakage(String proNum) {
		ComponentName comp = new ComponentName("android.test.ui", "android.test.ui.Topmost");
		Intent intent = new Intent();
		intent.putExtra("num",proNum);
		intent.setComponent(comp);			
		startActivity(intent);
		}
	

	@Override
	public void setUserVisibleHint(boolean isVisibleToUser)
	{
		super.setUserVisibleHint(isVisibleToUser);
		
		if(isVisibleToUser)
		{
			Intent intent = new Intent();
			intent.putExtra("page", 1);
			intent.setAction("com.konka.launcher.PAGE_VISIBILITY");
			getActivity().sendBroadcast(intent);
		}
	}
}
           

焦點框移動和圖檔放大效果大體思路:

利用framelayout布局,将邊框圖檔先隐藏,根據使用者焦點變化擷取目前view大小和位置,當圖檔擷取焦點,選擇框覆寫顯示,同時設定圖檔和選擇框動畫,所有變化放在onfocuschange中處理

public class OnFocusChangeLis implements OnFocusChangeListener {

	//public Context mContext;
	public Animation focusAnimation;
	public Animation defocusAnimation;
	public Animation focusPicAnimation;
	public Animation defocusPicAnimation;
	public ImageView focus_img;
	public  ImageButton imageButton;
	private int normal_focus_width_diff;
	private int normal_focus_height_diff;
	
	public OnFocusChangeLis(){						
		// 焦點框寬高差異值
		normal_focus_width_diff = 48;
		normal_focus_height_diff =50;
		
		focusAnimation = new ScaleAnimation(1.0f,1.1f,1.0f,1.1f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
		focusAnimation.setDuration(100);
		focusAnimation.setFillAfter(true);
		
		defocusAnimation = new ScaleAnimation(1.0f,1.0f,1.0f,1.0f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
		defocusAnimation.setDuration(50);
		defocusAnimation.setFillAfter(false);
		
		focusPicAnimation = new ScaleAnimation(1.0f,1.1f,1.0f,1.1f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
		focusPicAnimation.setDuration(100);
		focusPicAnimation.setFillAfter(true);
		
		defocusPicAnimation = new ScaleAnimation(1.0f,1.0f,1.0f,1.0f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
		defocusPicAnimation.setDuration(50);
		defocusPicAnimation.setFillAfter(false);
	}
	
	@Override
	public void onFocusChange(View v, boolean hasFocus) {
		
			focus_img = Refrences.getFocusImg(v);
			//focus_img = MainTabLive.focus_img;	

		if(hasFocus){
			showFocusImg(v);
			
		}
		else{
			dismissFocusImg();
			v.startAnimation(defocusPicAnimation);
		}
	}

	public void dismissFocusImg() {
		focus_img.startAnimation(defocusAnimation);
		focus_img.setVisibility(View.INVISIBLE);
	}

	public void showFocusImg(View v) {
		if (v == null)
		{
			return;
		}		
		FrameLayout.LayoutParams focusImgParams = (FrameLayout.LayoutParams) focus_img.getLayoutParams();
		focusImgParams.width = v.getWidth()
				+ normal_focus_width_diff;
		focusImgParams.height = v.getHeight()
				+ normal_focus_height_diff;
		
		focusImgParams.leftMargin = v.getLeft()- normal_focus_width_diff / 2-2;
		focusImgParams.topMargin = v.getTop()- normal_focus_height_diff / 2;
		
		focus_img.setLayoutParams(focusImgParams);
		
		focus_img.setVisibility(View.VISIBLE);
		focus_img.startAnimation(focusAnimation);
		v.startAnimation(focusPicAnimation);
		focus_img.bringToFront();
		
	}

}
           

源碼下載下傳位址:http://download.csdn.net/detail/u011403718/9005397