This article is from netease Cloud community

Author: Sun Youjun


preface

Here are several solutions to TV problems, if you are not interested in this actually do not need to read.

These days, there is a requirement to produce a TV version app. Before, I didn’t have a specific understanding of the difference between THE TV version app and the mobile app, so I did some research and wrote some demos. Indeed, several problems occurred in the process. A began to encounter these problems, just give it a try and find a lot of have no solution, in line with the foreign affairs ask Google, the search for a pair of, also have no results, may be the TV people do less, the search on the net is according to the sample of Google’s official implements a just, so careful research about these problems, The solutions to these problems are described here in the hope that others can avoid detours, and if there are better solutions, we also hope that we can discuss and share.

The development process

Although Google officially wrote that mobile apps can run on Tv without making too many changes, there are still some differences between the two, and some Settings should be made for THE Tv version. The first is the configuration file changes, need to configure the following attributes in the AndroidManifest:

<uses-feature
    android:name="android.hardware.touchscreen"
    android:required="false"/>
<uses-feature
    android:name="android.software.leanback"
    android:required="true"/>Copy the code

At the same time also need to configure an action for android. The intent. The action. The MAIN, the category for android. The intent. The category. The Activity of LEANBACK_LAUNCHER, similar to the following:

<activity
    android:name="im.yixin.home.HomeActivity"
    android:label="@string/app_name"
    android:screenOrientation="landscape">
    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>

        <category android:name="android.intent.category.LEANBACK_LAUNCHER"/>
    </intent-filter>
</activity>Copy the code

If not remember the content of the need to configure the above actually has nothing to do, also can create a new TV project, created by default TV project already contains the configuration, and the project is equivalent to a demo, can be directly run a project, which contains a lot of TV development controls, if you want to learn it is also very good learning materials, In fact, the follow-up content is also based on the content here for reference learning.

As a side note, the TV sample program in the Samples of Android SDK cannot be directly imported, and many things need to be modified. However, the substance is no different from the newly created project, so we can learn without importing the sample program.

According to the previous example figure, the main configuration page is as follows:

<? xml version="1.0" encoding="utf-8"? > <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/global_bg"
    android:orientation="vertical"
    android:paddingLeft="42dp"
    android:paddingRight="42dp">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="@dimen/gap_86_dp"
        android:clickable="true">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:drawableLeft="@drawable/tv_logo"
            android:drawablePadding="@dimen/gap_8_dp"
            android:gravity="center"
            android:text="@string/itv_name"
            android:textColor="@color/white"
            android:textSize="@dimen/text_size_20"/>

        <TextView
            android:id="@+id/settings_tab"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_alignParentRight="true"
            android:layout_marginRight="@dimen/gap_45_dp"
            android:background="@drawable/navigation_tab_bar_selector"
            android:focusable="true"
            android:gravity="center"
            android:text="@string/setting"
            android:textColor="@color/navigation_text_selector"
            android:textSize="@dimen/text_size_20"/>

        <TextView
            android:id="@+id/contact_tab"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_marginRight="@dimen/gap_45_dp"
            android:layout_toLeftOf="@id/settings_tab"
            android:background="@drawable/navigation_tab_bar_selector"
            android:focusable="true"
            android:gravity="center"
            android:text="@string/contact"
            android:textColor="@color/navigation_text_selector"
            android:textSize="@dimen/text_size_20"/>

        <TextView
            android:id="@+id/dial_tab"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_marginRight="@dimen/gap_65_dp"
            android:layout_toLeftOf="@id/contact_tab"
            android:background="@drawable/navigation_tab_bar_selector"
            android:focusable="true"
            android:gravity="center"
            android:text="@string/dial"
            android:textColor="@color/navigation_text_selector"
            android:textSize="@dimen/text_size_20"/>
    </RelativeLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:layout_marginBottom="@dimen/gap_50_dp"
        android:background="@color/gray1"/>

    <FrameLayout
        android:id="@+id/tab_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></FrameLayout>
</LinearLayout>Copy the code

The interface code is as follows:

public class HomeActivity extends Activity implements View.OnClickListener { public static void start(Context context) {  Intent intent = new Intent(context, HomeActivity.class); context.startActivity(intent); } private static final String[] TAGS = {"dial"."contact"."my"};

    private FragmentManager manager;

    private int showTabIndex = -1;

    private TextView dialTab;
    private TextView contactTab;
    private TextView myTab;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        findViews();
        setViewsListener();
        init();
        selectTab(0);
    }

    private void findViews() {
        dialTab = (TextView) findViewById(R.id.dial_tab);
        contactTab = (TextView) findViewById(R.id.contact_tab);
        myTab = (TextView) findViewById(R.id.settings_tab);
    }

    private void setViewsListener() {
        dialTab.setOnClickListener(this);
        contactTab.setOnClickListener(this);
        myTab.setOnClickListener(this);
    }

    private void init() {
        manager = getFragmentManager();
    }

    private void selectTab(int index) {
        if (index == showTabIndex) {
            return;
        }
        dialTab.setSelected(index == 0);
        contactTab.setSelected(index == 1);
        myTab.setSelected(index == 2);
        FragmentTransaction transaction = manager.beginTransaction();
        hideFragment(showTabIndex, transaction);
        showTabIndex = index;
        showFragment(showTabIndex, transaction);
        transaction.commit();
    }

    private void hideFragment(int tabIndex, FragmentTransaction transaction) {
        Fragment fragment = getFragmentByIndex(tabIndex);
        if(fragment ! = null) { transaction.hide(fragment); } } private Fragment getFragmentByIndex(int index) {if (index >= 0 && index < TAGS.length) {
            return manager.findFragmentByTag(TAGS[index]);
        }
        return null;
    }

    private void showFragment(int tabIndex, FragmentTransaction transaction) {
        Fragment fragment = getFragmentByIndex(tabIndex);
        if (fragment == null) {
            switch (tabIndex) {
                case 0:
                    fragment = new DialFragment();
                    break;
                case1: /* fragment = new ContactFragment(); */ fragment = new VerticalGridFragment();break;
                case 2:
                    fragment = new MyFragment();
                    break;
            }
            transaction.add(R.id.tab_container, fragment, TAGS[tabIndex]);
            //transaction.addToBackStack(TAGS[tabIndex]);
        } else {
            transaction.show(fragment);
        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.dial_tab:
                selectTab(0);
                return;
            case R.id.contact_tab:
                selectTab(1);
                return;
            case R.id.settings_tab:
                selectTab(2);
                //                VerticalGridActivity.start(this);
                return; }}}Copy the code

The interface mainly adopts Fragment to realize three interfaces, namely, the dial page, friends and Settings interface. The dial interface also contains two sub-fragments. Let’s continue to look at the dial interface and friends interface.


Netease Cloud Free experience pavilion, 0 cost experience 20+ cloud products!

For more information about NETEASE’s r&d, product and operation experience, please visit netease Cloud Community


Related articles: [recommended] General inventory of common data cleaning methods