Существующие патчи для Android Tabwidget, чтобы разрешить вкладки на левой стороне? - PullRequest
5 голосов
/ 17 августа 2010

Мой работодатель заставляет меня работать над приложением для Android с очень специфическими требованиями к пользовательскому интерфейсу.В частности, нам нужен интерфейс, который выглядит точно так же, как интерфейс TabWidget.Тем не менее, наличие вкладок на левой стороне является обязательным условием.Мы не собираемся развертывать это приложение на любых телефонах Android, оно предназначено для домашнего устройства, и поэтому у нас не возникнет проблем с нарушением каких-либо конструктивных соображений, которые может иметь платформа Android.

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

Что нам действительно нужно, так это выбросить весь наш прототип кода пользовательского интерфейса в обмен на использование встроенного 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);
}

Если у кого-то есть какая-либо информация, я был бы очень признателен.

Ответы [ 2 ]

1 голос
/ 14 июля 2011

(Обратите внимание, что я добавил лучший ответ ниже, за чертой. Я оставляю этот лучший ответ на тот случай, если он лучше соответствует чьим-либо потребностям.)

Да, я имел дело с той же проблемой. У меня есть несколько неуклюжее решение. Я заметил, что вы можете вращать практически любой вид с помощью 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. Другие вкладки нужно будет повернуть назад аналогичным образом. Некоторое время я возился с этим, и могут быть некоторые вещи, которые не нужны. Например, mainView. Я думаю, что это не должно быть там. Да, и если 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-файл определяет пустой вкладку с вкладками справа. Просто добавьте вкладки в свой код; для этого есть сообщения. Скопируйте / измените / сделайте все, что вам нужно, чтобы он соответствовал вашим потребностям. Кроме того, поскольку это круто, я добавил вид прокрутки вокруг вкладки, поэтому он автоматически разрешит прокрутку, если у вас слишком много вкладок. Избавься от этого, если не хочешь. Есть свиток в основном из http://java.dzone.com/articles/scrolling-tabs-android. Ууу!

1 голос
/ 17 августа 2010

У меня была эта проблема с вкладками внизу.В итоге я просто скопировал все фоновые рисунки вкладок и сделал кнопки с полями для рисования с состоянием и текстовым цветом, которые выглядели как вкладки, которые управляли ViewFlipper в главной панели пользовательского интерфейса для переключения между представлениями.

...