基于Android Tv制作一个Tv桌面(三)

基于Android Tv制作一个Tv桌面(三),第1张

概述基于AndroidTv制作一个Tv桌面(三)接下来我们就开始分析一下代码部分,这里我就转载其他人写的吧,我一开始也是参考这篇文章的。当然,我自己也添加了我自己在开发过程中写的代码和注释,对于新手来说没有这些注释还真的消耗头发转载地址:https://blog.csdn.net/lzybilian/article/d 基于AndroID Tv制作一个Tv桌面(三)

接下来我们就开始分析一下代码部分,这里我就转载其他人写的吧,我一开始也是参考这篇文章的。
当然,我自己也添加了我自己在开发过程中写的代码和注释,对于新手来说没有这些注释还真的消耗头发

转载地址:https://blog.csdn.net/lzybilian/article/details/80001032

(AndroIDManifest.xml)

<uses-permission androID:name="androID.permission.INTERNET" />   //这是申请网络的权限<uses-permission androID:name="androID.permission.RECORD_AUdio" />  //这是申请开发音频的权限<uses-feature    androID:name="androID.harDWare.touchscreen"    androID:required="false" />           //因为电视一般不支持触屏,所以需要声明一下权限<uses-feature    androID:name="androID.software.leanback"    androID:required="true" />     //使用一些TV下面的控件时,需要的声明<activity    androID:name=".MainActivity"    androID:banner="@drawable/app_icon_your_company"    androID:icon="@drawable/app_icon_your_company"    androID:label="@string/app_name"    androID:logo="@drawable/app_icon_your_company"    androID:screenorIEntation="landscape">    <intent-filter>        <action androID:name="androID.intent.action.MAIN" />                //因为我做的是桌面,所以加上了这两句		<category androID:name="androID.intent.category.HOME" />	        <category androID:name="androID.intent.category.DEFAulT" />    	    	//这个地方与手机端开发区别较大,这个主要是声明了这是一个TV项目,如果不加这个,那么运行在TV上时,是找不到这个应用的运行图标的    	//但是我依然找不到图标哈哈,以后发现了问题所在再写下来吧        <category androID:name="androID.intent.category.LEANBACK_LAUNCHER" />      </intent-filter></activity>

然后我就打开了MainActivity.xml,然后我发现里面竟然是空的。随后我就打开了MainActivity的资源文件。

<fragment xmlns:androID="http://schemas.androID.com/apk/res/androID"    xmlns:tools="http://schemas.androID.com/tools"    androID:ID="@+ID/main_browse_fragment"    androID:name="com.example.administrator.myfirst.MainFragment"  //这里是关键点,原来里面是引用了一个碎片。    androID:layout_wIDth="match_parent"    androID:layout_height="match_parent"    tools:context="com.example.administrator.myfirst.MainActivity"      tools:deviceids="tv"    tools:ignore="MergeRootFrame" />

然后就可以打开MainFragment.java。里面有四个方法,我们一一来分析一下。

//这些也写出来吧,不然看起来耗头发 	private static final String TAG = "MainFragment";    private static final int BACKGROUND_UPDATE_DELAY = 300;    private static final int GRID_ITEM_WIDTH = 200;    private static final int GRID_ITEM_HEIGHT = 200;    private final Handler mHandler = new Handler();    private Drawable mDefaultBackground;    private displayMetrics mMetrics;    private Timer mBackgroundTimer;    private String mBackgroundUri;    private BackgroundManager mBackgroundManager;    private List<ResolveInfo> apps_List = MainActivity.apps;    private List<String> sys_apps_name = MainActivity.system_app_name;    private List<String> my_apps_name = MainActivity.my_app_name;    private List<String> apps_name = MainActivity.name;    private List<String> apps_pak = MainActivity.pak;    private List<String> apps_cla = MainActivity.cla;
public voID onActivityCreated(Bundle savedInstanceState) {    Log.i(TAG, "onCreate");    super.onActivityCreated(savedInstanceState);    prepareBackgroundManager();    setupUIElements();    loadRows();    setupEventListeners();}

这里大家一看就明白这个方法的作用,初始化。

private voID prepareBackgroundManager() {    mBackgroundManager = BackgroundManager.getInstance(getActivity());    mBackgroundManager.attach(getActivity().getwindow());	//设置右边应用区域的背景颜色,被这个东西坑惨了ContextCompat.getcolor(),看了下面的代码才反应过来	//其实我也不知道它的原理是什么,参考百度吧    mBackgroundManager.setcolor(ContextCompat.getcolor(getActivity(), R.color.search_opaque));    mDefaultBackground = getResources().getDrawable(R.drawable.default_background);    mMetrics = new displayMetrics();    getActivity().getwindowManager().getDefaultdisplay().getMetrics(mMetrics);}private voID setupUIElements() {    // setBadgeDrawable(getActivity().getResources().getDrawable(    // R.drawable.vIDeos_by_Google_banner));    setTitle(getString(R.string.browse_Title)); // Badge, when set, takes precedent    // over Title    setheadersstate(headerS_ENABLED);    setheadersTransitionOnBackEnabled(false); //这里是设置左边引导的显示与否。    // set fastLane (or headers) background color    setBrandcolor(getResources().getcolor(R.color.background_gradIEnt_start));  //设置左边引导的背景色    // set search icon color    setSearchAffordancecolor(getResources().getcolor(R.color.search_opaque));}

这个方法主要作用是产生页面数据

private voID loadRows() {    List<MovIE> List = MovIEList.setupMovIEs();  //MovIE一个实现了序列化的Bean。setupMovIEs()是产生movIE数据的方法    mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());  //页面数据的适配器    CardPresenter cardPresenter = new CardPresenter();         //这个比较重要下面贴上源码   int sys_app_layer = 0;   int my_app_layer = 0;   if((sys_apps_name.size() % 8) == 0)   {   		sys_app_layer = (sys_apps_name.size() / 8);   }   else   {       sys_app_layer = (sys_apps_name.size() / 8) +1;   }	//(字怎么变黄了???)   if((my_apps_name.size() % 8) == 0)   {       my_app_layer = (sys_apps_name.size() / 8);   }   else   {       my_app_layer = (sys_apps_name.size() / 8) +1;   }	//应领导要求,将app分成系统应用和第三方应用   int i;   headerItem header1 = new headerItem(0, MovIEList.MOVIE_category[0]);   for (i = 0; i < sys_app_layer; i++) {       ArrayObjectAdapter ListRowAdapter = new ArrayObjectAdapter(cardPresenter);       for (int j = 0; j < 8 && ((8*i + j) < sys_apps_name.size()); j++) {           //Log.d(TAG,"List.get["+(8*i+j)+"]:"+List.get(8*i + j));           ListRowAdapter.add(List.get(8*i + j));       }       if(i == 0)       {           rowsAdapter.add(new ListRow(header1, ListRowAdapter));       }       else       {           rowsAdapter.add(new ListRow(ListRowAdapter));       }   }   headerItem header2 = new headerItem(i, MovIEList.MOVIE_category[1]);   for (i = 0; i < my_app_layer; i++) {       ArrayObjectAdapter ListRowAdapter = new ArrayObjectAdapter(cardPresenter);       for (int j = 0; j < 8 && ((8*i + j) < my_apps_name.size()); j++) {           //Log.d(TAG,"List.get["+(8*i+j)+"]:"+List.get(8*i + j));           ListRowAdapter.add(List.get(8*i + j + sys_apps_name.size()));       }       if(i == 0)       {           rowsAdapter.add(new ListRow(header2, ListRowAdapter));       }       else       {           rowsAdapter.add(new ListRow(ListRowAdapter));       }   }   headerItem grIDheader = new headerItem(i, "PREFERENCES");    GrIDItemPresenter mGrIDPresenter = new GrIDItemPresenter();    ArrayObjectAdapter grIDRowAdapter = new ArrayObjectAdapter(mGrIDPresenter); //里面传了一个Presenter grIDRowAdapter.add(getResources().getString(R.string.grID_vIEw));    grIDRowAdapter.add(getString(R.string.error_fragment));    grIDRowAdapter.add(getResources().getString(R.string.personal_settings));    mRowsAdapter.add(new ListRow(grIDheader, grIDRowAdapter));  //看了这个应该很清晰了    setAdapter(mRowsAdapter); //最后将mRowsAdapter设置}

主要就是实现了每个控件的绑定,设置数据

public class CardPresenter extends Presenter {    private static final String TAG = "CardPresenter";    private static final int CARD_WIDTH = 313;    private static final int CARD_HEIGHT = 176;    private static int sSelectedBackgroundcolor;    private static int sDefaultBackgroundcolor;    private Drawable mDefaultCardImage;    private static voID updateCardBackgroundcolor(ImageCardVIEw vIEw, boolean selected) {        int color = selected ? sSelectedBackgroundcolor : sDefaultBackgroundcolor;        // Both background colors should be set because the vIEw's background is temporarily visible        // during animations.        vIEw.setBackgroundcolor(color);        vIEw.findVIEwByID(R.ID.info_fIEld).setBackgroundcolor(color);    }    @OverrIDe    public VIEwHolder onCreateVIEwHolder(VIEwGroup parent) {        Log.d(TAG, "onCreateVIEwHolder");        sDefaultBackgroundcolor = parent.getResources().getcolor(R.color.default_background);        sSelectedBackgroundcolor = parent.getResources().getcolor(R.color.selected_background);        /*         * This template uses a default image in res/drawable, but the general case for AndroID TV         * will require your resources in xhdpi. For more information, see         * https://developer.androID.com/training/tv/start/layouts.HTML#density-resources         */		//下面这个mDefaultCardImage我将它移到了onBindVIEwHolder方法里面        //mDefaultCardImage = parent.getResources().getDrawable(R.drawable.movIE);        ImageCardVIEw cardVIEw = new ImageCardVIEw(parent.getContext()) {            @OverrIDe            public voID setSelected(boolean selected) {                updateCardBackgroundcolor(this, selected);  //这句很关键,它实现了当选择改变的时候,选中效果的出现                super.setSelected(selected);            }        };        cardVIEw.setFocusable(true);        cardVIEw.setFocusableIntouchMode(true);        updateCardBackgroundcolor(cardVIEw, false);        return new VIEwHolder(cardVIEw);    }    @OverrIDe    public voID onBindVIEwHolder(Presenter.VIEwHolder vIEwHolder, Object item) {        MovIE movIE = (MovIE) item;		//这里是根据item的Title与列表apps_name做对比,目的是获得i,获得准确的apps_icon		//至于为什么这样做,我会在文章后面画个图解释		for(int i=0; i<apps_name.size(); i++)        {            if(((MovIE) item).getTitle() == apps_name.get(i))            {                mDefaultCardImage = apps_icon.get(i);            }        }        ImageCardVIEw cardVIEw = (ImageCardVIEw) vIEwHolder.vIEw;        Log.d(TAG, "onBindVIEwHolder");        if (movIE.getCardImageUrl() != null) {            cardVIEw.setTitleText(movIE.getTitle());            //cardVIEw.setContentText(movIE.getStudio());			//这里是设置layout与父组件边框的距离,我没有找到调节父组件之间的距离的方法			//领导又觉得它们挤着慌,只好改一下这里了			FrameLayout.LayoutParams layout = new FrameLayout.LayoutParams(            FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);            layout.setmargins(30, 15, 30, 15);			//设置图标与父控件的距离,这里可以调节图标大小和形状			//说到这不得不承认我真的是菜,我没有找到将图标设置成原图的方法,只能这样把它硬挤成型            ImageVIEw imageVIEw = cardVIEw.getMainImageVIEw();            imageVIEw.setpadding(75, 25, 75, 25);            imageVIEw.setScaleType(ImageVIEw.ScaleType.FIT_XY);            cardVIEw.setMainImageDimensions(CARD_WIDTH, CARD_HEIGHT);            GlIDe.with(vIEwHolder.vIEw.getContext())                    .load(movIE.getCardImageUrl())                    .centerCrop()                    .error(mDefaultCardImage)                    .into(layout);        }    }    @OverrIDe    public voID onUnbindVIEwHolder(Presenter.VIEwHolder vIEwHolder) {        Log.d(TAG, "onUnbindVIEwHolder");        ImageCardVIEw cardVIEw = (ImageCardVIEw) vIEwHolder.vIEw;        // Remove references to images so that the garbage collector can free up memory        cardVIEw.setBadgeImage(null);        cardVIEw.setMainImage(null);    }}

这个方法设置了监听

private voID setupEventListeners() {    setonSearchClickedListener(new VIEw.OnClickListener() {		        @OverrIDe        public voID onClick(VIEw vIEw) {        	//左上角搜索点击事件            Toast.makeText(getActivity(), "Implement your own in-app search", Toast.LENGTH_LONG)                    .show();        }    });		//item的监听    setonItemVIEwClickedListener(new ItemVIEwClickedListener());    setonItemVIEwSelectedListener(new ItemVIEwSelectedListener());}

解释一下之前的那个循环吧,下面图中的大黑框是屏幕,黑框外面的小框则是超出屏幕外面的图标,图标下面都有app的名字我这里是把app的各种信息分别存在不同的列表中,位置也是对应好的;但是一打开应用我就傻眼了,app名字和图标对应不上,原因就在于它加载图标时先把屏幕内的填上,再搞屏幕外面的。所以我就只能根据app名字去找到对应的图标,再将它加载进去,这样就不会乱了

总结

以上是内存溢出为你收集整理的基于Android Tv制作一个Tv桌面(三)全部内容,希望文章能够帮你解决基于Android Tv制作一个Tv桌面(三)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1052587.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存