web-dev-qa-db-ja.com

グライドを使用したズームとマスク

私はグライドを使用してこれを達成する方法を学ぶために誰かが正しい方向に私を向けることができるかどうかを見ているだけです...

  • コンテンツのあるページがあります。

  • コンテンツは1つの画像として表示されます(例:雑誌のページの画像)

  • 読みやすいモードで、テキストコンテンツの最初のブロックを中心にしてズームし、残りをマスクしたい

  • [次へ]をクリックすると、テキストコンテンツの次のブロックに移動し、最近使用して再ズームしたい

  • 「戻る」をクリックすると、テキストコンテンツの前のブロックに移動し、最近使用して再ズームします

  • マスクは常に長方形ですが、サイズはコンテンツに合わせて常に変化します

以下に簡単な画像をいくつか示して、私の意味を示します。私たちは現在、これを配置するimageviewと4つの黒いビューを使用してこれを行っていますが、それは非常にぎくしゃくしており、ミスアライメントが発生しやすい傾向があります。グライドでこれを達成できますか?

皆さんありがとう!

"Full Page" View"Easy Reading" View

6
Psest328

以下を試すことができます。

あなたの状況をシミュレートするために、私はテキストで画像を作成する必要がありました
座標と寸法が事前定義されているブロックなので、次のようにしました:

1)3つのテキストビューを持つ単純な相対レイアウトを作成しました:

<RelativeLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:id="@+id/rl"
Android:background="@Android:color/black"
Android:layout_height="match_parent">

<TextView
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:gravity="center"
    Android:textAlignment="center"
    Android:padding="40dp"
    Android:layout_marginTop="50dp"
    Android:layout_marginBottom="10dp"
    Android:layout_alignParentEnd="true"
    Android:layout_alignParentRight="true"
    Android:text="Text Block 1"
    Android:textSize="30sp"
    Android:textColor="@Android:color/white"
    Android:id="@+id/tv1"/>

<TextView
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:gravity="center"
    Android:textAlignment="center"
    Android:padding="40dp"
    Android:layout_marginBottom="20dp"
    Android:layout_alignParentStart="true"
    Android:layout_alignParentLeft="true"
    Android:layout_below="@id/tv1"
    Android:text="Text Block 2"
    Android:textSize="30sp"
    Android:textColor="@Android:color/white"
    Android:id="@+id/tv2"/>

<TextView
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:gravity="center"
    Android:textAlignment="center"
    Android:padding="40dp"
    Android:layout_marginBottom="40dp"
    Android:layout_alignParentEnd="true"
    Android:layout_alignParentRight="true"
    Android:layout_below="@id/tv2"
    Android:text="Text Block 3"
    Android:textSize="30sp"
    Android:textColor="@Android:color/white"
    Android:id="@+id/tv3"/>

</RelativeLayout>

2)以下のアクティビティを作成しました:

public class TextBlockActivity extends AppCompatActivity {

private final String TAG = TextBlockActivity.class.getSimpleName();
private RelativeLayout rl;
private Map<String, float[]> text_map = new HashMap<>();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    rl = (RelativeLayout) findViewById(R.id.rl);
    rl.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            rl.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            for (int i = 0; i < rl.getChildCount(); i++) {
                View child = rl.getChildAt(i);
                if (child instanceof TextView) {
                    TextView tv = (TextView) child;
                    float[] c = new float[]{tv.getX(), tv.getY(), tv.getWidth(), tv.getHeight()};
                    Log.i(TAG, (i + 1) + " x: " + c[0] + " y: " + c[1] + " w: " + c[2] + " h: " + c[3]);
                }
            }
        }
    });
}

}

3)実際のデバイスでプロジェクトを構築し、アクティビティを実行して、各テキストブロックの座標と寸法を取得し、画面のスクリーンショットを撮りました。

座標と寸法(x、y、w、h):

  • テキストブロック1:351、180、729、361
  • テキストブロック2:0、541、729、361
  • テキストブロック3:351、962、729、361

スクリーンショット:

screenshot

4)座標、寸法、画像を取得したら、次のことを行いました:

-MainActivity.class:

public class MainActivity extends AppCompatActivity {

private final String TAG = MainActivity.class.getSimpleName();
private ImageView iv;
private PhotoView pv_preview;
private LinearLayout ll;
private Button b_back;
private Button b_next;
private Map<String, float[]> text_blocks_coordinates_map = new HashMap<>();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    iv = (ImageView) findViewById(R.id.iv);
    pv_preview = (PhotoView) findViewById(R.id.pv_preview);
    ll = (LinearLayout) findViewById(R.id.ll);
    b_back = (Button) findViewById(R.id.b_back);
    b_back.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            if (pv_preview.getTag() != null) {

                float[] c_current = text_blocks_coordinates_map.get((String) pv_preview.getTag());

                if (c_current != null) {

                    TreeMap<Float, String> possible_targets_map = new TreeMap<>(); //Float y:coordinate, String key
                    for (Map.Entry<String, float[]> entry : text_blocks_coordinates_map.entrySet()) {
                        //do comparison based on the y coordinate only
                        //assuming that no two blocks of text will have the same y coordinate and different x coordinate (will be horizontally aligned)
                        if (entry.getValue()[1] < c_current[1]) {
                            possible_targets_map.put(entry.getValue()[1], entry.getKey());
                        }
                    }

                    //TreeMap will sort content according to their key values in decreasing order
                    // from the treeMap of possible targets, create a list containing the values of the treeMap above (which are the keys of text_blocks_coordinates_map)
                    List<String> possible_targets_list = new ArrayList<>();
                    for (Map.Entry<Float, String> entry : possible_targets_map.entrySet()) {
                        possible_targets_list.add(entry.getValue());
                    }

                    //take the last item in this possible_targets_list as key and get content from text_blocks_coordinates_map
                    if (!possible_targets_list.isEmpty()) {
                        changePreview(iv, possible_targets_list.get(possible_targets_list.size() - 1), text_blocks_coordinates_map.get(possible_targets_list.get(possible_targets_list.size() - 1)));
                    }
                }
            }
        }
    });
    b_next = (Button) findViewById(R.id.b_next);
    b_next.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            if (pv_preview.getTag() != null) {

                float[] c_current = text_blocks_coordinates_map.get((String) pv_preview.getTag());

                if (c_current != null) {

                    TreeMap<Float, String> possible_targets_map = new TreeMap<>();
                    for (Map.Entry<String, float[]> entry : text_blocks_coordinates_map.entrySet()) {
                        //do comparison based on the y coordinate only
                        //assuming that no two blocks of text will have the same y coordinate and different x coordinate (will be horizontally aligned)
                        if (entry.getValue()[1] > c_current[1]) {
                            possible_targets_map.put(entry.getValue()[1], entry.getKey());
                        }
                    }

                    //TreeMap will sort content according to their key values in decreasing order
                    // from the treeMap of possible targets, create a list containing the values of the treeMap above (which are the keys of text_blocks_coordinates_map)
                    List<String> possible_targets_list = new ArrayList<>();
                    for (Map.Entry<Float, String> entry : possible_targets_map.entrySet()) {
                        possible_targets_list.add(entry.getValue());
                    }

                    //take the first item in this possible_targets_list as key and get content from text_blocks_coordinates_map
                    if (!possible_targets_list.isEmpty()) {
                        changePreview(iv, possible_targets_list.get(0), text_blocks_coordinates_map.get(possible_targets_list.get(0)));
                    }
                }
            }
        }
    });

    //These are the coordinates of text blocks inside the image
    text_blocks_coordinates_map.put(String.valueOf(1), new float[]{351, 180, 729, 361});
    text_blocks_coordinates_map.put(String.valueOf(2), new float[]{0, 541, 729, 361});
    text_blocks_coordinates_map.put(String.valueOf(3), new float[]{351, 962, 729, 361});

    iv.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {

            Log.e(TAG, "Touching Image View");

            float x = motionEvent.getX();
            float y = motionEvent.getY();

            for (Map.Entry<String, float[]> entry : text_blocks_coordinates_map.entrySet()) {
                float[] c = entry.getValue();
                if (x > c[0] && x < (c[0] + c[2])
                        && y > c[1] && y < (c[1] + c[3])) {

                    changePreview(iv, entry.getKey(), entry.getValue());

                }
            }
            return false;
        }
    });
}

@Override
public void onBackPressed() {
    if (pv_preview.getVisibility() == View.VISIBLE) {
        iv.setVisibility(View.VISIBLE);
        ll.setVisibility(View.GONE);
        pv_preview.setVisibility(View.GONE);
    } else {
        super.onBackPressed();
    }
}

private void changePreview(ImageView iv, String k, float[] c) {

    //The only method that works efficiently,
    // but it is deprecated
    iv.setDrawingCacheEnabled(true);
    iv.buildDrawingCache();
    Bitmap bitmap = Bitmap.createBitmap(iv.getDrawingCache());
    iv.destroyDrawingCache();

    Bitmap resource = Bitmap.createBitmap(bitmap, Math.round(c[0]), Math.round(c[1]), Math.round(c[2]), Math.round(c[3]));
    pv_preview.setImageBitmap(resource);

    iv.setVisibility(View.GONE);
    ll.setVisibility(View.VISIBLE);
    pv_preview.setVisibility(View.VISIBLE);

    //set pv_preview tag as the key of text block content currently
    // previewed (will be used inside next and back)
    pv_preview.setTag(k);


}

}

-activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
xmlns:tools="http://schemas.Android.com/tools"
Android:background="@Android:color/black"
Android:layout_height="match_parent">

<LinearLayout
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:padding="20dp"
    Android:id="@+id/ll"
    Android:visibility="gone"
    Android:weightSum="100">

    <Button
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:id="@+id/b_back"
        Android:gravity="center"
        Android:text="Back"
        Android:layout_weight="50"/>

    <Button
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:id="@+id/b_next"
        Android:gravity="center"
        Android:text="Next"
        Android:layout_weight="50"/>

</LinearLayout>

<ImageView
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:id="@+id/iv"
    tools:ignore="contentDescription"
    Android:src="@drawable/image"/>

<com.github.chrisbanes.photoview.PhotoView
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:visibility="gone"
    Android:layout_below="@id/ll"
    Android:id="@+id/pv_preview"/>

   </RelativeLayout>

-結果:

result

1
Brainnovo