2011-09-16 12 views
0

私は簡単なAndroidレイアウトの質問をしています。どのように画面サイズに関係なく、イメージを重ね合わせることができますか?

サイズが480x800の画像を撮影してください。画像は表示されますが、詳細があるものが優先されます。 この画像をlarge.pngとします。

ここで、画像のランダムな部分をカットして新しい画像に貼り付けて、small.pngと呼んでください。

次に、両方の画像を撮り、大きな画像を画面全体の背景として置き、小さな画像をパズルのように他の画像と一致するように配置してみましょう。画像。

簡単な解決策は、(あなたがFrameLayoutのように背景を設定した場合、または1)FrameLayoutImageViews 2とを持っていること、そしてほんの少しのImageViewある程度のマージン値を与えるだろう。例:

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout android:layout_width="fill_parent" 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_height="fill_parent"> 

    <ImageView android:layout_width="fill_parent" 
     android:layout_height="fill_parent" android:background="@drawable/large" 
     android:layout_gravity="top|left" /> 

    <ImageView android:layout_width="wrap_content" 
     android:layout_gravity="top|left" android:layout_height="wrap_content" 
     android:background="@drawable/small" android:layout_marginLeft="100dp" 
     android:layout_marginTop="100dp" /> 

</FrameLayout> 

これは、少なくともテストしている現在のデバイスの解像度で動作するはずです。 この解決策を異なる画面解像度の他のデバイスで使用したり、現在の向きを変更したりするときに問題が発生します。

もう1つの解決策は、マージンを使用する代わりに重量の力を与える複数のLinearLayoutsですが、この解決方法は面倒でXML(およびメモリ使用量)を大きくし、常に機能するわけではありませんおそらく計算上の制限のために小さな画像のために空白を作成することができます。

この問題の最適な解決策は何ですか?私はOpenGLの使用を避けようとしています。

私が見つけることができる唯一の可能な解決策は、小さな画像を取り、それを他の画像のマスクのように設定することで、他の画像と同じサイズを持ち、周囲に空白があります。しかし、これはいつも可能なわけではありません。時には、扱う画像がたくさんあり、これらの規則に従うものもありません。


は、具体的に:彼らは上に示されているものを画面に関係なく、完璧にフィットしませんように

は、私は、別の画像の上に画像を入れたいです。

たとえば、顔の画像があり、同じサイズの複数の目画像がある場合は、顔の目を変えるためにそれらを切り替えることができます。


多分私が最初にそれを書かれている必要があります:彼らは、彼らが上に示されているものを画面に関係なく、完璧にフィットしませんように

iは、別の画像の上に画像を入れたいです。 例えば、あなたが顔の画像を持っていて、同じサイズの複数の目画像を持っている場合、私は顔の目を変えるためにそれらを切り替えることができます。


私はこれもこれほど簡単だったと思います。私は別の方法でそれを解決しようとしました。これは、必要に応じてグローバルにも解決します。元の画面と現在の画面の比率に応じてすべてを拡大しようとしました。他のすべての画面でスケールアップします。 通常、それはうまく動作しますが、時々空白がどこから来るのか、計算エラーのためか、画面間のアスペクト比が異なるためです。 ここで、このコードをチェックしてください。何が間違っているのかを教えてください。(btw、このコードはdpが異なる密度のpxの量を変更するため、次元単位がpxでdpでない場合にのみ機能します):

public class GlobalPercentageLayoutTestActivity extends Activity 
    { 
    private static final int DEFALT_TARGET_WIDTH =480,DEFALT_TARGET_HEIGHT=800; 
    private int    targetWidth; 
    private int    targetHeight; 
    private static int  screenWidth,screenHeight; 

    public int convertToNewXCoordinate(int x) 
    { 
    int newX=x*screenWidth/this.targetWidth; 
    return newX; 
    } 

    public int convertToNewYCoordinate(int y) 
    { 
    int newY=y*screenHeight/this.targetHeight; 
    return newY; 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
    super.onCreate(savedInstanceState); 
    DisplayMetrics metrics=new DisplayMetrics(); 
    getWindowManager().getDefaultDisplay().getMetrics(metrics); 
    screenWidth=metrics.widthPixels; 
    screenHeight=metrics.heightPixels; 
    this.targetWidth=DEFALT_TARGET_WIDTH; 
    this.targetHeight=DEFALT_TARGET_HEIGHT; 
    View root=getLayoutInflater().inflate(R.layout.main,null); 
    prepare(root); 
    setContentView(root); 
    } 

    private void scaleSingleView(View v) 
    { 
    LayoutParams lp=v.getLayoutParams(); 
    if(lp!=null) 
     { 
     // set margins: 
     if(lp instanceof MarginLayoutParams) 
     { 
     MarginLayoutParams ml=(MarginLayoutParams)lp; 
     int t=ml.topMargin,b=ml.bottomMargin,l=ml.leftMargin,r=ml.rightMargin; 
     ml.setMargins(convertToNewXCoordinate(l),convertToNewYCoordinate(t),convertToNewXCoordinate(r),convertToNewYCoordinate(b)); 
     } 
     // set size: 
     int w=lp.width,h=lp.height; 
     if(w!=ViewGroup.LayoutParams.FILL_PARENT&&w!=ViewGroup.LayoutParams.WRAP_CONTENT&&w!=ViewGroup.LayoutParams.MATCH_PARENT) 
     lp.width=convertToNewXCoordinate(w); 
     if(h!=ViewGroup.LayoutParams.FILL_PARENT&&h!=ViewGroup.LayoutParams.WRAP_CONTENT&&h!=ViewGroup.LayoutParams.MATCH_PARENT) 
     lp.height=convertToNewYCoordinate(h); 
     // set padding: 
     int t=v.getPaddingTop(),b=v.getPaddingBottom(),l=v.getPaddingLeft(),r=v.getPaddingRight(); 
     t=convertToNewYCoordinate(t); 
     b=convertToNewYCoordinate(b); 
     l=convertToNewXCoordinate(l); 
     r=convertToNewXCoordinate(r); 
     v.setPadding(l,t,r,b); 
     } 
    } 

    private void prepare(View v) 
    { 
    scaleSingleView(v); 
    if(v instanceof ViewGroup) 
     { 
     ViewGroup parent=(ViewGroup)v; 
     int numberOfChildren=parent.getChildCount(); 
     for(int i=0;i<numberOfChildren;++i) 
     { 
     View view=parent.getChildAt(i); 
     prepare(view); 
     } 
     } 
    } 
    } 

皆さん、私はあなたが私が記述しています問題を理解してないと思うので、私は謎の方法でそれを説明します。

は、次の2枚の画像を取り、彼らはそれぞれother.notesに収まるように、パズルのように2 imageViewsを使用して、それらを一緒に置く:

1.最も重要なこと:イメージはできるだけ多くのスペースを埋める作ります現在の画面解像度に基づいて可能ですが、他のビュー(レイアウトも含む)を配置したい可能性があるので、imageViewsだけでなく、すべてのビュー(余白、パディング、サイズ)のアスペクト比を維持し、可能なすべての解像度

2.「large.png」という名前のイメージはバックグラウンドにあるべきですが、「small.png」という名前のイメージはもう一方の内側にあり、穴を埋めるはずです

3.小さな画像が大きな画像の穴全体に収まるように、穴の内部に空白を入れないでください。これはスケーリングを達成するのに成功して以来重要ですが、私はなぜ空きスペースがあるのか​​を知ることができませんでした(おそらくアンドロイドのサンプリングの問題のためでしょうか?)& linearLayoutのトリックでさえありません。 http://imageshack.us/photo/my-images/402/testvk.png/

4.bonus:ここ は私がここに書かれたコードを使用して成功してきたものの一例だとしても、実行時にそれを動作させるため、私は具体的な余裕を持って実行時に新しいビューを置けばそのようにパディングとサイズを指定すると、画面の解像度に応じてこれらのプロパティを自動的に拡大/縮小します。それが難しい場合は、レイアウトの前/後に新しく作成したビューで何をすべきか教えてください。

5.opengl、surfaceViewなどは素晴らしいですが、私が探しているものではありません。私は単純なアンドロイドのビューを使用して任意の解像度で動作するソリューションが欲しいです。例として(そして私はそれが良い例だと思っています)、あなたのアンドロイドウェブブラウザを使って、htmlに特別なモバイルタグを持たないウェブサイトを訪れてください。利用可能なスペースに応じてすべてが伸びているので、試したすべてのデバイスで同じようにウェブサイトが表示されていることがわかります。私は今、誰もが私の質問であるかを理解することを願ってい http://imageshack.us/g/703/largee.png/

:ここ

は、すべての画像です。

+0

実行中の問題について具体的に説明できますか? – emmby

+0

私はいくつかの情報を追加しましたが、司会者はそれを削除してメインの投稿に2回挿入しました。モデレータ、私はPMへの方法を知らないので、更新をマージしてください(そしてあなたはまた、ここでそれについて話す部分を削除することもできます)。いずれにしても 、私が話している問題は、あなたが汚いトリックをしない限り、アンドロイドは自動的に活動のすべてをスケールすることができないということです。これは実際には欠けている機能であり、余白やパディングにはあまり目的がありません。 多分アンドロイド4は、このような状況ではなく、Googleがタブレットやその他のデバイス用のAndroidをマージする予定です。 –

+0

私の答えは私の編集をご覧ください。多分助けてくれるでしょう –

答えて

1

あなたはコードでそれを行う必要があります:

は、表示寸法(またはイメージのコンテナの大きさ)を決定します。

次に、画像表示/コンテナのサイズの比率を計算します。これにより、オーバーレイ画像のサイズを変更する必要がある比率が決まります。

最後に、計算された比率を使用してオーバーレイを再度配置する必要がある位置のサイズ変更された座標を計算します。

あなたは:)

は、あなたがXMLであなたのImageViewsにパラメータを設定することができます

EDITをやっていますか?

android:adjustViewBounds="true" 
0

は、私は100%あなたが何をしようとして理解すればわからないんだけど、あなたは、画面上の画像の上にそのくらいのコントロールをしたい場合、あなたは来るLunarLander例をチェックアウトし、SurfaceViewを検討すべきですSDKを使用します。

1

私のために働く。 2つのビットマップイメージを渡して、互いにオーバーレイします。

public static Bitmap overlay(String patho,String patht) { 
    Bitmap bmp1= BitmapFactory.decodeFile(patho); 
    Bitmap bmp2= BitmapFactory.decodeFile(patht); 
    Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(), bmp1.getHeight(), bmp1.getConfig()); 
    Canvas canvas = new Canvas(bmOverlay); 

    Matrix m=new Matrix(); 
    canvas.drawBitmap(bmp1, m, null); 

    canvas.drawBitmap(bmp2, m,null); 
    return bmOverlay; 
} 
関連する問題