Androidの画面サイズを管理する
さまざまな画面サイズに対応するアプリケーションを作成しましょう。このチュートリアルでは、Androidで利用可能な画面サイズは数多くありますが、これを管理するためのいくつかの戦略を検討します。
レベル:中級
プラットフォーム:Android, macOS, Windows
クラス: Desktop,AffineTransform,TabbedComponent
スタート
このチュートリアルでは、JUCEを使用してAndroidプラットフォーム上で異なる画面サイズを管理するためのいくつかの戦略を説明します。このチュートリアルには、いくつかのデモプロジェクトがあります。これらのプロジェクトのダウンロード・リンクは、チュートリアルの関連するセクションにあります。
各セクションのこのステップでヘルプが必要な場合は、以下を参照してください。Tutorial: Projucer Part 1: Getting started with the Projucer.
デモ・プロジェクト
このチュートリアルで提供されるデモ・プロジェクトは、JUCEを使用してAndroidプラットフォーム上で異なる画面サイズを管理するためのいくつかの異なる方法を示しています。大まかに、これらの方法は以下の通りです:
- メインコンポーネント内の子コンポーネントのサイズ変更
- トランスフォームを使用したメインコンポーネントのサイズ変更
- 方向によって異なるコンポーネントのレイアウトを設計する
- サイズごとに異なるコンポーネントレイアウトを設計
アンドロイドの画面サイズ
特にフルスクリーン操作を期待するデバイス(モバイルデバイスなど)では、すべての画面サイズとさまざまなデバイスの向きに効果的なユーザーインタフェースをデザインすることが課題となります。これは、多くの画面サイズと解像度が存在するアンドロイド・プラットフォームでは特に難しいことです。ここでは主に3つの問題がある:
- 物理的サイズ:画面の物理的な大きさを標準単位で表したもの(一般的な単位は画面の対角線上の距離で、単位はインチ)
- 決議:ピクセル単位の画面解像度
- オリエンテーション: デバイスの向き(横向きか縦向きか)
物理的なサイズと解像度の関係は重要である。特に、物理的なピクセルが標準的な解像度のスクリーンよりも小さく、高密度に配置されている高解像度スクリーンを考える際には重要です。特定の物理的な画面サイズと解像度の組み合わせは、画面のドット・パー・インチ(DPI)。これはスクリーンピクセル密度.これは、標準的な密度の画面上のピクセルとして、各次元で、「ソフトウェア」ピクセルのスペースを占める物理的なピクセルの数である。
アプリケーションによっては、物理的な大きさが最も重要な場合もある。例えば、繊細な指の動きからなる複雑なインタラクションを使用するアプリケーションなどです。この場合、画面サイズと典型的なユーザーの手の大きさが重要です。他のアプリケーションでは、画面のDPIがより重要です。例えば、DPIが高くてもフォントサイズが小さければテキストは読みやすくなります。しかし、スクリーン上の物理的なサイズで測定した場合、テキストの可読性には限界があります。アプリケーションを設計する際には、物理的なサイズと解像度(したがってDPI)の両方を考慮に入れる必要がある場合があります。
デフォルトでは、JUCEはその座標系をスクリーンのピクセル密度に基づいてスケーリングします。これは、高密度のスクリーンで描かれた図形やテキストは、標準的な密度のスクリーンで描かれたものとほぼ同じ物理的サイズに見えるはずであることを意味します。JUCEでは、特定のディスプレイに関する情報にDesktopクラスがあります。ここでは、利用可能なディスプレイと、どのディスプレイが「メインディスプレイ」としてマークされているかを確認できます(特に複数のディスプレイがある場合)。
残念ながら、JUCEがディスプレイのDPIを取得するためにアクセスできる値は近似値に過ぎません(すべてのスクリーンデバイスがこの情報を適切に報告するわけではないため)。つまり、ユーザーの画面の物理的なサイズを正確に測定することはできません。しかしDesktopクラスは、アプリケーションのニーズに応じてユーザー・インタフェースを拡張するためのガイドとして十分なはずだ。
この後の各例では、子コンポーネントとしてResizingComp
これは、親コンポーネント(MainContentComponent
).
これ らのプロジェクトをmacOSまたはWindowsでテストすると、メイン・ウィンドウの幅と高さを動的に変更できます。これはある程度機能しますが、テスト目的以外ではプロジェクトの機能として意図されていません。プロジェクトは、サイズの頻繁な変更を想定して設計されています。例えば、アプリケーションの起動時や、ユーザーがAndroidデバイスを回転させた時などに、1回だけ設定します。
子コンポーネントのサイズ変更(単純なサイズ変更)
このセクションのデモ・プロジェクトのダウンロードはこちらから:PIP|ZIP.プロジェクトを解凍し、最初のヘッダーファイルをProjucerで開く。
この例では、スライダーとボタンのコレクションを含む単純なインタフェースを使用します。これらの子コンポーネントには、それぞれ画面の高さ(端の小さな枠を除く)の割合が与えられている。水平方向でも同様のアプローチが可能です。簡単にするために、スライダーとボタンは、画面の幅全体を占めるだけです(ここでも、小さなボーダーを除きます)。画面が縦向きで、サイズ が数百ピクセルの場合、以下のスクリーンショットのようになります:

横向きの場合は、以下のスクリーンショットのようになります:

コンポーネントの配列
ボタンとスライダーをResizingComp
クラスではOwnedArrayテンプレート・クラスでは、これらの子コンポーネントは自動的に削除されます。ResizingComp
デストラクタ)。まずResizingComp
コンストラクタでColourオブジェクトの色を設定します。これらは、ボタン、スライダーの親指、スライダートラックの色を設定するために使用されます:
ResizingComp()
{
juce::Array colours { juce::Colour (0xffb3c3Da), juce::Colour (0xff5973b8), juce::Colour (0xffd65667), juce::Colour (0xffd99154),
juce::Colour (0xffe5ad6c), juce::Colour (0xffecc664), juce::Colour (0xffefe369), juce::Colour (0xffdddB74) };
これらは偶然にもJUCEのロゴの色である!
そしてfor()
ループで複数のボタンを割り当て、設定する:
for (auto i = 0; i < 6; ++i)
{
auto* button = buttons.add (new juce::TextButton (juce::String ("Button ") + juce::String (i + 1)));
addAndMakeVisible (button);
button->setColour (juce::TextButton::buttonColourId,
colours.getUnchecked (i % colours.size()));
}
スライダーも同じように設定されている(ただし、面白さを保つために、色の配列を使って色の選択を混ぜている)。
for (auto i = 0; i < 6; ++i)
{
auto* slider = sliders.add (new juce::Slider());
addAndMakeVisible (slider);
slider->setColour (juce::Slider::thumbColourId,
colours.getUnchecked ((buttons.size() + i) % colours.size()));
slider->setColour (juce::Slider::backgroundColourId,
colours.getUnchecked ((buttons.size() + i + 2) % colours.size()).withAlpha (0.4f));
slider->setColour (juce::Slider::trackColourId,
colours.getUnchecked ((buttons.size() + i + 2) % colours.size()));
slider->setColour (juce::Slider::textBoxTextColourId, juce::Colours::black);
}
カスタムスライダーのサムサイズを使用する
タッチスクリーン・インタフェースでより使いやすくするため、スライダーの親指は通常標準サイズより大きくなるようにカスタマイズされています。そのためにLookAndFeel_V4をオーバーライドした。LookAndFeel::getSliderThumbRadius()関数である。
class CustomLookAndFeel : public juce::LookAndFeel_V4
{
public:
int getSliderThumbRadius (juce::Slider& slider) override
{
return juce::jmin (slider.getWidth(), slider.getHeight()) / 2;
}
};
このクラスのインスタンスをResizingComp
クラスである:
juce::OwnedArray buttons;
juce::OwnedArray sliders;
CustomLookAndFeel lf;
};
そして、最後にResizingComp
コンストラクタで、このコンポーネントとそのすべての子コンポーネントのルック&フィールを設定します。
setLookAndFeel (&lf);
そして、我々のResizingComp
デストラクタでは、これをnullptrに設定する。
~ResizingComp() override
{
setLookAndFeel (nullptr);
}
ボタンとスライダーのサイズ変更
の中でResizingComp::resized()
関数では、ボタンとスライダーの配列を繰り返し処理し、その境界を設定する:
void resized() override
{
auto space = 8;
auto widgetHeight = (getHeight() - space) / (buttons.size() + sliders.size()) - space;
for (auto* button : buttons)
button->setBounds (space, space + (widgetHeight + space) * buttons.indexOf (button),
getWidth() - space - space, widgetHeight);
for (auto* slider : sliders)
slider->setBounds (space, space + (widgetHeight + space) * (sliders.indexOf (slider) + buttons.size()),
getWidth() - space - space, widgetHeight);
}
ここでは、定数値(8)を使用してコンポーネントを分離します。そして、利用可能な高さと "ウィジェット"(ボタンとスライダー)の数に基づいて "ウィジェットの高さ "を計算します。
画面サイズが小さすぎると、以下のスクリーンショットのようにインタフェースが使用できなくなり、読めなくなる:
