TabHost / TabWidget - 缩放背景图像?

发布于 2024-10-08 15:12:31 字数 4622 浏览 0 评论 0 原文

我需要缩放 TabWidget 背景图像,以便它们保持纵横比。
我正在使用 TabHost 和 TabWidget。然后我使用 setBackgroundDrawable 来设置图像。

我在这里找到了一个接近的答案 - 选项卡小部件中的背景忽略缩放。但是,我不确定在哪里添加新的 Drawable 代码。 (使用HelloTabWidget示例,我的模块都没有使用RelativeLayout,并且我没有看到“tabcontent”的任何布局。)

我还发现了这个线程 - Android:缩放可绘制图像或背景图像?。根据它的说法,听起来我必须预先缩放我的图像,这违背了使它们可缩放的整个目的。

我还发现了另一个线程,其中有人对 Drawable 类进行了子类化,因此它要么无法缩放,要么可以正确缩放。我现在找不到它,但是当您应该能够执行像 mTab​​.setScaleType(centerInside) 这样的简单操作时,这似乎需要经历很多事情。

这是我的代码:

main.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 图像,但它们最终太小了。

那么,解决这个问题的最佳方法是什么?

I need to scale my TabWidget background images so they maintain aspect ratio.
I am using a TabHost with a TabWidget. I am then using setBackgroundDrawable to set the images.

I found a close answer here - Background in tab widget ignore scaling. However, I'm not sure just where to add the new Drawable code. (Working with the HelloTabWidget example, none of my modules use RelativeLayout, and I don't see any layout for "tabcontent".)

I also found this thread - Android: Scale a Drawable or background image?. According to it, it sounds like I would have to pre-scale my images, which defeats the whole purpose of making them scaleable.

I also found another thread where someone subclassed the Drawable class so it would either not scale, or it would scale properly. I can't find it now, but that seems like a LOT to go through when you should just be able to do something simple like mTab.setScaleType(centerInside).

Here's my code:

main.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>

main activity:

        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));
}

I also tried 9patch images, but they wind up being too small.

So, what's the best way to go about this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

儭儭莪哋寶赑 2024-10-15 15:12:31

看看这个,让我知道它是否适合您。

自定义 Android 选项卡

Check this out and let me know whether it worked for you.

Custom Android Tab

秋心╮凉 2024-10-15 15:12:31

我怀疑您之所以努力寻找一种开箱即用的方法来执行背景图像缩放,是因为它通常不被视为良好的做法。图像缩放往往会引入伪影和条带,这会使您的 UI 看起来很糟糕。例外情况是在 Imageview 中,但我认为此类提供的缩放支持更多是为了支持照片或 Web 内容(即您的应用程序中未附带的图像)等内容。

您的 UI 布局的设计方式应确保任何基于资源的背景图像都应根据设备的密度/屏幕尺寸预先缩放至正确的分辨率。换句话说,您应该使用 支持多屏幕开发指南。

然后,UI 应进行布局,以便可以处理设备之间屏幕尺寸的任何细微差异,而无需缩放其所包含视图的背景图像。显然,我不知道您建议的 UI 是什么样子,因此很难提出任何具体建议,但通常我使用简单的背景块颜色或 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());

I suspect the reason you're struggling to find an out-of-the-box way to perform background image scaling is that it's not generally seen as good practice. Scaling of images tends to introduce artifacts and banding which can make your UI look nasty. The exception to this is within an Imageview, but I would argue the scaling support this class provides is more intended to support things like photos or web content (i.e. images you have not shipped with your app).

Your UI layout should be designed in such a way that any resource-based background images should be pre-scaled to the correct resolution for the density / screen size of the device. In other words you should be providing multiple versions of each drawable to cater for multiple screen densities and sizes using the resource folder naming convention outlined in the Supporting Multiple Screens dev guide.

The UI should then be laid out such that any slight differences of screen size between devices can be handled without needing to scale background images of its contained views. Obviously I don't know what your proposed UI looks like so it's difficult to make any concrete suggestions, but generally I use simple background block colors or ShapeDrawables to dynamically fill the space between views.

However, if you're really really sure you want to scale your background images despite the preaching above :-), why not try using a ScaleDrawable to wrap your existing drawable?

If you know the height and width of both your view and background image drawable, then you can do something like:

Drawable backgroundDrawable = getResources().getDrawable(R.drawable.tab_license_off); 
tempView.setBackgroundDrawable(
    new ScaleDrawable(
        backgroundDrawable,
        Gravity.CENTER,
        tempView.getWidth() / backgroundDrawable.getIntrinsicWidth(),
        tempView.getHeight() / backgroundDrawable.getIntrinsicHeight());
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文