TabHost / TabWidget - Масштабировать фоновое изображение?

Мне нужно масштабировать фоновые изображения TabWidget, чтобы они сохраняли соотношение сторон.
Я использую TabHost с TabWidget. Затем я использую setBackgroundDrawable для установки изображений.

Я нашел близкий ответ здесь - Фон в виджете вкладки игнорирует масштабирование. Однако я не уверен, куда добавить новый код Drawable. (Работая с примером HelloTabWidget, ни один из моих модулей не использует RelativeLayout, и я не вижу никакого макета для «контента вкладок».)

Я также нашел эту ветку - Android: масштабирование Drawable или фонового изображения?. Согласно этому, похоже, что мне придется предварительно масштабировать свои изображения, что противоречит самой цели сделать их масштабируемыми.

Я также нашел еще один поток, в котором кто-то создал подкласс класса Drawable, чтобы он либо не масштабировался, либо масштабировался правильно. Я не могу найти его сейчас, но кажется, что это МНОГО, когда вы должны просто сделать что-то простое, например, mTab.setScaleType(centerInside).

Вот мой код:

основной.xml:

<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/tabhost"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/main_background"> 
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
    <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_weight="1"/>        
    <TabWidget
            android:id="@android:id/tabs"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" 
            android:layout_weight="0"/>
    </LinearLayout>
</TabHost>

основная деятельность:

        tabHost.setOnTabChangedListener(new OnTabChangeListener() { 
            TabHost changedTabHost = getTabHost();
            TabWidget changedTabWidget = getTabWidget();
            View changedView = changedTabHost.getTabWidget().getChildAt(0);

            public void onTabChanged(String tabId) { 
                int selectedTab = changedTabHost.getCurrentTab();
                TabWidget tw = getTabWidget();

                if(selectedTab == 0) {
                    //setTitle("Missions Timeline");
                    View tempView = tabHost.getTabWidget().getChildAt(0);
                    tempView.setBackgroundDrawable(getResources().getDrawable(R.drawable.tab_timeline_on));
                    tempView = tabHost.getTabWidget().getChildAt(1);
                    tempView.setBackgroundDrawable(getResources().getDrawable(R.drawable.tab_map_off));
                    tempView = tabHost.getTabWidget().getChildAt(2);
                    tempView.setBackgroundDrawable(getResources().getDrawable(R.drawable.tab_search_off));
                    tempView = tabHost.getTabWidget().getChildAt(3);
                    tempView.setBackgroundDrawable(getResources().getDrawable(R.drawable.tab_news_off));
                    tempView = tabHost.getTabWidget().getChildAt(4);
                    tempView.setBackgroundDrawable(getResources().getDrawable(R.drawable.tab_license_off));
                            //ImageView iv = (ImageView)tabHost.getTabWidget().getChildAt(0).findViewById(android.R.id.icon); 
                            //iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_timeline_on)); 
                            //iv = (ImageView)tabHost.getTabWidget().getChildAt(1).findViewById(android.R.id.icon); 
                            //iv.setImageDrawable(getResources().getDrawable(R.drawable.tab_map_off)); 
                    } else if (selectedTab == 1) {
                        //setTitle("Spinoffs Around You");
                        View tempView = tabHost.getTabWidget().getChildAt(0);
                        tempView.setBackgroundDrawable(getResources().getDrawable(R.drawable.tab_timeline_off));
                        tempView = tabHost.getTabWidget().getChildAt(1);
                        tempView.setBackgroundDrawable(getResources().getDrawable(R.drawable.tab_map_on));
                        tempView = tabHost.getTabWidget().getChildAt(2);
                        tempView.setBackgroundDrawable(getResources().getDrawable(R.drawable.tab_search_off));
                        tempView = tabHost.getTabWidget().getChildAt(3);
                        tempView.setBackgroundDrawable(getResources().getDrawable(R.drawable.tab_news_off));
                        tempView = tabHost.getTabWidget().getChildAt(4);
                        tempView.setBackgroundDrawable(getResources().getDrawable(R.drawable.tab_license_off));
}

Я также пробовал изображения 9patch, но они оказались слишком маленькими.

Итак, как лучше всего это сделать?


person user359519    schedule 16.12.2010    source источник


Ответы (2)


Я подозреваю, что причина, по которой вы изо всех сил пытаетесь найти готовый способ масштабирования фонового изображения, заключается в том, что это обычно не считается хорошей практикой. Масштабирование изображений имеет тенденцию приводить к появлению артефактов и полос, которые могут сделать ваш пользовательский интерфейс неприятным. Исключением является Imageview, но я бы сказал, что поддержка масштабирования, предоставляемая этим классом, больше предназначена для поддержки таких вещей, как фотографии или веб-контент (т. е. изображения, которые вы не поставляли с вашим приложением).

Ваш макет пользовательского интерфейса должен быть разработан таким образом, чтобы любые фоновые изображения на основе ресурсов были предварительно масштабированы до правильного разрешения для плотности / размера экрана устройства. Другими словами, вы должны предоставить несколько версий каждого drawable для удовлетворения различных плотностей и размеров экрана, используя соглашение об именовании папок ресурсов, описанное в Поддержка нескольких экранов руководство разработчика.

Затем пользовательский интерфейс должен быть организован таким образом, чтобы любые небольшие различия в размерах экрана между устройствами можно было обрабатывать без необходимости масштабирования фоновых изображений содержащихся в нем представлений. Очевидно, я не знаю, как выглядит предложенный вами пользовательский интерфейс, поэтому трудно сделать какие-либо конкретные предложения, но обычно я использую простые цвета фоновых блоков или ShapeDrawable для динамического заполнения пространства между представлениями.

Однако, если вы действительно действительно уверены, что хотите масштабировать фоновые изображения, несмотря на проповедь выше :-), почему бы не попробовать использовать ScaleDrawable, чтобы обернуть существующий рисунок?

Если вы знаете высоту и ширину как вашего вида, так и фонового изображения, вы можете сделать что-то вроде:

Drawable backgroundDrawable = getResources().getDrawable(R.drawable.tab_license_off); 
tempView.setBackgroundDrawable(
    new ScaleDrawable(
        backgroundDrawable,
        Gravity.CENTER,
        tempView.getWidth() / backgroundDrawable.getIntrinsicWidth(),
        tempView.getHeight() / backgroundDrawable.getIntrinsicHeight());
person tomtheguvnor    schedule 02.11.2011

Проверьте это и дайте мне знать, сработало ли это для вас.

Пользовательская вкладка Android

person mH16    schedule 25.11.2011