2016-05-09 10 views
0

フレームレイアウトにコード内のTextViewを追加しようとしています。これはフレームレイアウトのzオーダーの画像ビューの上に位置します。究極の目的は、画像とそれにオーバーレイされているテキストを示すframelayoutからのスクリーンショットの作成を許可することです。私はXMLで作成されたテキストビューを使用していますが、動的コードバージョンでは使用できません。ビットマップメソッドを作成すると、テキストボックスの幅が0であるというエラーが返されます。以下のコードでは、framelayoutのキャプチャされたイメージに画像が含まれていないため、問題として識別する画像としてtextviewだけをキャプチャしようとしています。期待どおりのtextviewの内容。これを行うことで、私は幅の誤差を見つけることができました。そして、これが問題の根であると信じています。 setWidthとLayoutParamsを使って、textviewの幅を設定しようとしました。最終的な結果は、テキストビューは、ハンドセット上ではっきりと見ることができるが、常に幅がないことである。私は動的な作成と0の幅になる既存のxmlの間に何かがないと思う。誰でも正しい方向に私を向けることができますか?FrameLayoutの動的に作成されたTextViewに幅がありません

public void applyTextToImage(View view) { 
    // Do something in response to button 

    //Hide the virtual keyboard 


    InputMethodManager inputManager = (InputMethodManager) getSystemService(this.INPUT_METHOD_SERVICE); 
    inputManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); 

    //Get the text to overlay on the image 
    EditText editText = (EditText) findViewById(R.id.edit_message); 
    String message = editText.getText().toString(); 

    //Bring the overlay layout to the front 
    //LinearLayout overlay_layout = (LinearLayout) findViewById(R.id.image_Overlay_Layout); 
    //overlay_layout.bringToFront(); 

    //Apply the new text to the text box 

    /* Old code to get the view that is shown in the layout 
    TextView text_overlay = (TextView) findViewById(R.id.image_Overlay); 
    text_overlay.bringToFront(); 
    text_overlay.setText(message); 
    */ 

    //New code to create a view dynamically instead 

    TextView text_Overlay = new TextView(this); 
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) { 
     text_Overlay.setId(Utils.generateViewId()); 
    } 
    else 
    { 
     text_Overlay.setId(TextView.generateViewId()); //static class 
    } 
    FrameLayout image_Layout = (FrameLayout) findViewById(R.id.image_Layout); 
    //View image_Layout = (View) findViewById(R.id.image_Layout); 
    //FrameLayout.LayoutParams fParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,FrameLayout.LayoutParams.WRAP_CONTENT); 
    FrameLayout.LayoutParams fParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,FrameLayout.LayoutParams.WRAP_CONTENT); 
    fParams.gravity = Gravity.CENTER; 

    // text_Overlay.setMaxWidth(image_Layout.getWidth()); 
    // text_Overlay.setWidth(image_Layout.getWidth()); 
    //image_Layout.addView(text_Overlay, fParams); 
    image_Layout.addView(text_Overlay, fParams); 
    Toast.makeText(this,"TextView Width: " + text_Overlay.getWidth(),Toast.LENGTH_LONG).show(); 

    //TODO: Something has forced the dynamic layout to not be saved in the bitmap try removing the params and set the values on the textview itself 
    //TODO: for some reason the width keeps coming back as 0 could be that the image_Layout is 0 too 

    text_Overlay.setGravity(Gravity.CENTER); 
    text_Overlay.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); 
    float pixels = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, getResources().getDisplayMetrics()); 
    //text_Overlay.setWidth(250dp); 

    text_Overlay.setTextSize(pixels); 
    text_Overlay.setTextColor(Color.RED); 
    text_Overlay.bringToFront(); 
    text_Overlay.setText(message); 
    text_Overlay.setVisibility(View.VISIBLE); 
    //End of new dynamic code 

    if (folderCheck()){ 
     try { 
      String filePath = getFilePath(); 
      int myId = text_Overlay.getId(); 

      Bitmap bitmap; 
      View v1 = findViewById(myId); 

      v1.setDrawingCacheEnabled(true); 

      v1.buildDrawingCache(); 

      bitmap = Bitmap.createBitmap(v1.getDrawingCache()); 
      v1.setDrawingCacheEnabled(false); 
      // End imported code 

      streamBitmapToFile(bitmap, filePath); 
     } 
     catch (Exception e) 
     { 
      Toast.makeText(this,e.getMessage(),Toast.LENGTH_LONG); 
      Log.e("Bitmap Creation","Couldn't create bitmap error as: " + e.toString()); 
     } 
    } 
} 

XMLコンテンツ

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:paddingBottom="@dimen/activity_vertical_margin" 
android:paddingLeft="@dimen/activity_horizontal_margin" 
android:paddingRight="@dimen/activity_horizontal_margin" 
android:paddingTop="@dimen/activity_vertical_margin"> 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:orientation="horizontal" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_alignParentTop="false"> 
    <!--app:layout_behavior="@string/appbar_scrolling_view_behavior" 
    tools:showIn="@layout/activity_my"--> 

    <EditText android:id="@+id/edit_message" 
     android:layout_weight="1" 
     android:layout_width="0dp" 
     android:layout_height="wrap_content" 
     android:hint="@string/edit_message" 
     android:enabled="false"/> 

    <Button android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="@string/button_send" 
     android:onClick="applyTextToImage" 
     android:enabled="false" 
     android:id="@+id/overlayButton"/> 

</LinearLayout> 

<FrameLayout 
    android:id="@+id/image_Layout" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_centerHorizontal="true" 
    android:layout_centerVertical="true"> 

    <ImageView 
     android:id="@+id/image_View" 
     android:layout_width="match_parent" 
     android:layout_height="250dp" /> 

    <!--<TextView 
     android:id="@+id/image_Overlay" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center" 
     android:textAlignment="center" 
     android:textSize="25dp" 
     android:textColor="#ff0000"/>--> 

</FrameLayout> 
<LinearLayout 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:layout_alignParentTop="false" 
android:gravity="bottom" 
android:layout_alignParentBottom="true" 
android:layout_centerHorizontal="true"> 

<Button android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="@string/open_gallery" 
    android:onClick="openGallery"> 
</Button> 

<Button android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="@string/new_image" 
    android:onClick="newImage"> 
</Button> 

</LinearLayout> 
</RelativeLayout> 

答えて

0

ビューがまだ測定されていないが、以下のよう

コードです。システムが別のレイアウト・パスを実行するまで、ビューはその幅をゼロとして報告します。

私の意見では、TextViewをXMLレイアウトに残して、必要なまで非表示(android:visibility="invisible")してから、setVisbility(View.VISIBLE)でプリオラマチックに表示する方がよいでしょう。 (goneに設定すると、測定もされません)。

+0

こんにちは、お返事ありがとうございます!私は、これらの(そして未知の数字)を複数追加する必要があります。なぜなら、これはコードを使って行う必要があるからです。コード内に別のレイアウトパスを強制する方法はありますか? –

+0

@PaleNeanderthalあなたはレイアウトパスを実行するよう要求することができますが、すぐには実行されません(つまり、要求をしてから次の行で 'getWidth()'を使うことはできません)。また、 'getWidth()'をすぐに使用できないのと同じ理由で、ビューがまだ描画されていないため、ビューの描画キャッシュを取得できません。 – Karakuri

+0

@ PaleNeanderthalあなたのニーズに応じて、 'ViewTreeObserver'クラスを見て、あなたに有用なコールバックインタフェースがあるかどうかを調べることができます。 – Karakuri

0

参考のために、Karakuriは弱点とそれらを解決するための道筋を指摘しました。

リスナー用に実装されたエクストラコードは次のとおりです。

IMAGE_CAPTURE_REQUESTED = true; 

    // New Listener 
    ViewTreeObserver vto = image_Layout.getViewTreeObserver(); 
    vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 
     @Override 
     public void onGlobalLayout() { 


      if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { 
       image_Layout.getViewTreeObserver().removeGlobalOnLayoutListener(this); 
      } 
      else 
      { 
       image_Layout.getViewTreeObserver().removeOnGlobalLayoutListener(this); 
      } 

      if (IMAGE_CAPTURE_REQUESTED) { 
       //int myId = text_Overlay.getId(); 
       //Toast.makeText(MyActivity.this, "Text Overlay Width " + text_Overlay.getWidth() ,Toast.LENGTH_LONG).show(); 
       overlayTextAndExportImage(); 
      } 
     } 
    }); //End New Listener 

新しいoverlayTextAndImportImageは、レイアウトが再描画された後にすべてのイメージ作成ルーチンを呼び出します。

関連する問題