Android tabwidget 的现有补丁允许左侧选项卡吗?

发布于 2024-09-14 18:29:58 字数 2215 浏览 11 评论 0原文

我的雇主让我开发一个具有非常具体的 UI 要求的 Android 应用程序。具体来说,我们需要一个看起来与 TabWidget 界面完全相同的界面。然而,将选项卡放在左侧是绝对必须的。我们不会将此应用程序部署到任何 Android 手机上,它用于内部设备,因此不会有任何违反 Android 平台可能具有的设计考虑因素的问题。

我们已经有了一个工作原型,它使用焦点侦听器和列表视图的组合将我们需要的功能组合在一起。它并不漂亮,我们对此还不是很有信心,但它暂时有效。

我们真正想要的是扔掉所有原型 UI 代码,以换取使用内置 TabWidget。但是,由于 TabWidget 被硬编码为仅适用于顶部的选项卡,因此这实际上并不是一个选项。

那么,我们希望有人有一个补丁或一组补丁,或者可能是一个自定义类,可以用侧面的选项卡来处理 TabWidget 功能?

TabWidget的相关代码在这里:http://www.google.com/codesearch /p?hl=en#uX1GffpyOZk/core/java/android/widget/TabWidget.java&q=android%20package:git://android.git.kernel.org%20lang:java%20tabwidget&sa=N&cd =1&ct=rc

并且硬编码为顶部选项卡的特定函数是

private void initTabWidget() {
    setOrientation(LinearLayout.HORIZONTAL);
    mGroupFlags |= FLAG_USE_CHILD_DRAWING_ORDER;

    final Context context = mContext;
    final Resources resources = context.getResources();

    if (context.getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.DONUT) {
        // Donut apps get old color scheme
        if (mLeftStrip == null) {
            mLeftStrip = resources.getDrawable(
                    com.android.internal.R.drawable.tab_bottom_left_v4);
        }
        if (mRightStrip == null) {
            mRightStrip = resources.getDrawable(
                    com.android.internal.R.drawable.tab_bottom_right_v4);
        }
    } else {
        // Use modern color scheme for Eclair and beyond
        if (mLeftStrip == null) {
            mLeftStrip = resources.getDrawable(
                    com.android.internal.R.drawable.tab_bottom_left);
        }
        if (mRightStrip == null) {
            mRightStrip = resources.getDrawable(
                    com.android.internal.R.drawable.tab_bottom_right);
        }
    }

    // Deal with focus, as we don't want the focus to go by default
    // to a tab other than the current tab
    setFocusable(true);
    setOnFocusChangeListener(this);
}

如果有人有任何信息,我将非常感激。

My employer is having me work on an android application with very specific UI requirements. Specifically, we need an interface that looks exactly like a TabWidget interface. However, having the tabs on the left hand side is an absolute must. We aren't going to be deploying this application to any android phones, its for an in house device, and as such don't have any problem violating any design considerations that the android platform might have.

We already have a working prototype that hacks together the functionality we need using a combination of focus listeners and list views. It isn't pretty, and we aren't very confident in it just yet, but it works for the time being.

What we'd really like is to throw all of our prototype UI code away in exchange for using the built in TabWidget. However, since TabWidget is hardcoded to only work with the tabs on top, this isn't really an option.

So, we are hoping that someone out there has a patch, or set of patches, or perhaps a custom class, that handles the TabWidget functionality with the tabs on the side instead?

The relevant code for the TabWidget is here: http://www.google.com/codesearch/p?hl=en#uX1GffpyOZk/core/java/android/widget/TabWidget.java&q=android%20package:git://android.git.kernel.org%20lang:java%20tabwidget&sa=N&cd=1&ct=rc

and the specific function that is hardcoded for being tabs on top is

private void initTabWidget() {
    setOrientation(LinearLayout.HORIZONTAL);
    mGroupFlags |= FLAG_USE_CHILD_DRAWING_ORDER;

    final Context context = mContext;
    final Resources resources = context.getResources();

    if (context.getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.DONUT) {
        // Donut apps get old color scheme
        if (mLeftStrip == null) {
            mLeftStrip = resources.getDrawable(
                    com.android.internal.R.drawable.tab_bottom_left_v4);
        }
        if (mRightStrip == null) {
            mRightStrip = resources.getDrawable(
                    com.android.internal.R.drawable.tab_bottom_right_v4);
        }
    } else {
        // Use modern color scheme for Eclair and beyond
        if (mLeftStrip == null) {
            mLeftStrip = resources.getDrawable(
                    com.android.internal.R.drawable.tab_bottom_left);
        }
        if (mRightStrip == null) {
            mRightStrip = resources.getDrawable(
                    com.android.internal.R.drawable.tab_bottom_right);
        }
    }

    // Deal with focus, as we don't want the focus to go by default
    // to a tab other than the current tab
    setFocusable(true);
    setOnFocusChangeListener(this);
}

If anyone has any information, I'd be much obliged.

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

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

发布评论

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

评论(2

知足的幸福 2024-09-21 18:29:58

我遇到过底部标签的问题。我最终只是复制了所有选项卡背景可绘制对象,并制作带有状态可绘制对象和文本颜色的按钮,这些按钮看起来像控制主 UI 窗格中的 ViewFlipper 来在视图之间切换的选项卡。

I've had this issue with tabs on the bottom. I ended up just copying all the tab background drawables and making buttons with stateful drawables and textcolor that looked like tabs which controlled a ViewFlipper in the main UI pane to switch between views.

紫南 2024-09-21 18:29:58

(请注意,我在下面添加了一个更好的答案,超过了该行。我将保留这个最上面的答案,以防它更适合其他人的需求。)

是的,我一直在处理同样的问题。我有一个有点笨拙的解决方案。我注意到你可以使用 setRotate 旋转几乎任何视图。不幸的是,这只是旋转其图像或其他东西,并不能完全处理问题或位置或大小或对齐。即便如此,我还是设法拼凑了一些东西来弥补它,尽管它只完成了一半(如果你旋转到纵向方向,则不太正常)。每当平板电脑旋转或重新排列布局或发生任何其他情况时,都会调用以下函数。

private LinearLayout llMain;
private LinearLayout ll1;
private LinearLayout mainView;
private TabHost myTabHost;

public void setStuff() {
    Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
    if (display.getOrientation() == 0 || display.getOrientation() == 2) {
        ViewGroup.LayoutParams lp = myTabHost.getLayoutParams();
        int top = 0;
        int left = 0;
        int height = 696;
        int width = 1280;
        int centerx = (width / 2) + left;
        int centery = (height / 2) + top;
        lp.height = width;
        lp.width = height;
        myTabHost.setLayoutParams(lp);
        myTabHost.setTranslationX(centerx - (height / 2));
        myTabHost.setTranslationY(centery - (width / 2));
        lp = mainView.getLayoutParams();
        lp.width = 1280;
        lp.height = 696;
        mainView.setLayoutParams(lp);
        lp = llMain.getLayoutParams();
        lp.width = 1280;
        lp.height = 696;
        llMain.setLayoutParams(lp);

        ll1.setRotation(-90);
        lp = ll1.getLayoutParams();
        lp.height = 696;
        lp.width = 1141;
        ll1.setLayoutParams(lp);
        left = 0;
        top = 0;
        height = 696;
        width = 1141;
        centerx = (width / 2) + left;
        centery = (height / 2) + top;
        ll1.setTranslationX(centery - (width / 2));
        ll1.setTranslationY(centerx - (height / 2));
        //ll1.setTranslationX(tx);
        //ll1.setTranslationY(ty);
    } else {
        ViewGroup.LayoutParams lp = myTabHost.getLayoutParams();
        int top = 0;
        int left = 0;
        int height = 1280;
        int width = 696;
        int centerx = (width / 2) + left;
        int centery = (height / 2) + top;
        lp.height = width;
        lp.width = height;
        myTabHost.setLayoutParams(lp);
        myTabHost.setTranslationX(centerx - (height / 2));
        myTabHost.setTranslationY(centery - (width / 2));
        lp = mainView.getLayoutParams();
        lp.width = 696;
        lp.height = 1280;
        mainView.setLayoutParams(lp);
        lp = llMain.getLayoutParams();
        lp.width = 696;
        lp.height = 1280;
        llMain.setLayoutParams(lp);

        ll1.setRotation(-90);
        lp = ll1.getLayoutParams();
        lp.height = 1141;
        lp.width = 696;
        ll1.setLayoutParams(lp);
        left = 0;
        top = 0;
        height = 1141;
        width = 696;
        centerx = (width / 2) + left;
        centery = (height / 2) + top;
        ll1.setTranslationX(centery - (width / 1));
        ll1.setTranslationY(centerx - (height / 1));
        //ll1.setTranslationX(tx);
        //ll1.setTranslationY(ty);
    }
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    setStuff();
    //setContentView(R.layout.main);
} 

llMain 包含 mainView 包含 myTabHost 包含 ll1;您需要在初始化代码中这样分配它们。这个想法是 TabHost 顺时针旋转,并且必须手动交换其尺寸,以便其容器现在知道它的尺寸/形状不同,否则边缘会被切断。此外,还进行了一些计算,以便它围绕正确的点旋转,或者至少最终到达正确的位置。结果并不总是有意义,所以我只是改变了一些东西,直到它起作用为止,至少在横向模式下是这样。 TabHost 的内容也会旋转,因此其中有代码将其旋转回来,至少是第一个选项卡,即 ll1。其他选项卡也需要类似地旋转回来。我在这个问题上折腾了一段时间,可能有些东西是不必要的。例如,主视图。我认为那不需要在那里。哦,如果 TabHost 位于不同的位置,则需要以某种方式调整数字。祝你好运。无论如何,我希望这对某人有帮助。伙计,Android GUI 太烦人了...我希望他们能修复它...不过,我承认,尽管存在所有障碍和挫折,任何组件的旋转都非常酷。我只是希望其他一切都像你期望的那样。


嘿,我刚刚想出了如何让它正确地做到这一点!标签保持水平,因此这可能是好事,也可能不是好事,具体取决于您想要什么,但无论如何:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="match_parent"
  android:layout_height="match_parent">
    <TabHost android:id="@android:id/tabhost" android:layout_width="match_parent" android:layout_height="match_parent">
        <LinearLayout android:id="@+id/linearLayout1" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal">
            <FrameLayout android:layout_width="fill_parent" android:layout_height="match_parent" android:layout_weight="1" android:id="@android:id/tabcontent"></FrameLayout>
            <ScrollView android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:fillViewport="true"
                android:scrollbars="none">          
                <TabWidget android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" android:id="@android:id/tabs"></TabWidget>
            </ScrollView>
        </LinearLayout>
    </TabHost>

</LinearLayout>

此 XML 文件定义了一个空 tabhost,其选项卡位于右侧。只需在代码中添加选项卡即可;周围有相关的帖子。复制/更改/做任何您需要做的事情以使其满足您的需求。另外,因为它很酷,所以我在选项卡小部件周围添加了滚动视图,因此如果您有太多选项卡,它会自动允许滚动。如果你不想要它,就把它扔掉。滚动的东西主要来自 http://java.dzone.com/articles/scrolling-tabs -android。耶!

(Note that I added a better answer further down, past the line. I'm leaving this top one in in case it better fits someone else's needs.)

Yeah, I've been dealing with the same issue. I have a somewhat clunky solution. I noticed that you can rotate pretty much any View with setRotate. Unfortunately, this only rotates its image, or something, and doesn't fully deal with issues or placement or size or alignment. Even so, I've managed to cobble together something that kinda compensates for it, though it's only half done (doesn't quite work right if you rotate to portrait orientation). The following gets called whenever the tablet is rotated or the layout gets rearranged or whatever.

private LinearLayout llMain;
private LinearLayout ll1;
private LinearLayout mainView;
private TabHost myTabHost;

public void setStuff() {
    Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
    if (display.getOrientation() == 0 || display.getOrientation() == 2) {
        ViewGroup.LayoutParams lp = myTabHost.getLayoutParams();
        int top = 0;
        int left = 0;
        int height = 696;
        int width = 1280;
        int centerx = (width / 2) + left;
        int centery = (height / 2) + top;
        lp.height = width;
        lp.width = height;
        myTabHost.setLayoutParams(lp);
        myTabHost.setTranslationX(centerx - (height / 2));
        myTabHost.setTranslationY(centery - (width / 2));
        lp = mainView.getLayoutParams();
        lp.width = 1280;
        lp.height = 696;
        mainView.setLayoutParams(lp);
        lp = llMain.getLayoutParams();
        lp.width = 1280;
        lp.height = 696;
        llMain.setLayoutParams(lp);

        ll1.setRotation(-90);
        lp = ll1.getLayoutParams();
        lp.height = 696;
        lp.width = 1141;
        ll1.setLayoutParams(lp);
        left = 0;
        top = 0;
        height = 696;
        width = 1141;
        centerx = (width / 2) + left;
        centery = (height / 2) + top;
        ll1.setTranslationX(centery - (width / 2));
        ll1.setTranslationY(centerx - (height / 2));
        //ll1.setTranslationX(tx);
        //ll1.setTranslationY(ty);
    } else {
        ViewGroup.LayoutParams lp = myTabHost.getLayoutParams();
        int top = 0;
        int left = 0;
        int height = 1280;
        int width = 696;
        int centerx = (width / 2) + left;
        int centery = (height / 2) + top;
        lp.height = width;
        lp.width = height;
        myTabHost.setLayoutParams(lp);
        myTabHost.setTranslationX(centerx - (height / 2));
        myTabHost.setTranslationY(centery - (width / 2));
        lp = mainView.getLayoutParams();
        lp.width = 696;
        lp.height = 1280;
        mainView.setLayoutParams(lp);
        lp = llMain.getLayoutParams();
        lp.width = 696;
        lp.height = 1280;
        llMain.setLayoutParams(lp);

        ll1.setRotation(-90);
        lp = ll1.getLayoutParams();
        lp.height = 1141;
        lp.width = 696;
        ll1.setLayoutParams(lp);
        left = 0;
        top = 0;
        height = 1141;
        width = 696;
        centerx = (width / 2) + left;
        centery = (height / 2) + top;
        ll1.setTranslationX(centery - (width / 1));
        ll1.setTranslationY(centerx - (height / 1));
        //ll1.setTranslationX(tx);
        //ll1.setTranslationY(ty);
    }
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    setStuff();
    //setContentView(R.layout.main);
} 

llMain contains mainView contains myTabHost contains ll1; you'll need to have assigned them as such in the initialization code. The idea is that the TabHost gets rotated clockwise, and its dimensions have to be manually swapped so that its containers know that it's a different size/shape, now, otherwise the edges get cut off. Also, it some calculations are done so that it get rotated around the right point, or at least ends up in the right place. The results didn't always make sense, so I just changed stuff until it worked, at least in landscape mode. The contents of the TabHost get rotated, too, so there's code in there that rotates it back, at least the first tab, which is ll1. Other tabs would need to be rotated back similarly. I messed around with this for a while, and there may be some things that are unnecessary. For example, the mainView. I think that doesn't need to be there. Oh, and if the TabHost is in a different place, the numbers will need to be adjusted somehow. Good luck with that. Anyway, I hope this helps somebody. Man, Android GUI is so aggravating...I wish they'd fix it.... I'll admit, though, that despite all the obstacles and frustrations, rotation of any component is pretty cool. I just wish everything else worked like you'd expect.


Hey, I just figured out how to get it to do it properly! The labels stay horizontal, so that may or may not be a good thing, depending on what you want, but anyway:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="match_parent"
  android:layout_height="match_parent">
    <TabHost android:id="@android:id/tabhost" android:layout_width="match_parent" android:layout_height="match_parent">
        <LinearLayout android:id="@+id/linearLayout1" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal">
            <FrameLayout android:layout_width="fill_parent" android:layout_height="match_parent" android:layout_weight="1" android:id="@android:id/tabcontent"></FrameLayout>
            <ScrollView android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:fillViewport="true"
                android:scrollbars="none">          
                <TabWidget android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" android:id="@android:id/tabs"></TabWidget>
            </ScrollView>
        </LinearLayout>
    </TabHost>

</LinearLayout>

This XML file defines an empty tabhost with the tabs on the right. Just add the tabs in your code; there're posts around for that. Copy/alter/do whatever you need to do to make it fit your needs. Also, because it's cool, I added a scroll view around the tabwidget, so it'll automatically allow scrolling if you have too many tabs. Get rid of it if you don't want it. Got the scroll thing mostly from http://java.dzone.com/articles/scrolling-tabs-android. Yay!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文