2

線でポイントして、テキストと適切な画像を一致させるアプリを作成しようとしています。

下の画像に示されているものとまったく同じアプリを作成したいと思います。

テキストビューのリストとその間の画像のグリッドビューを作成しました。線形レイアウトです。 テキストビューをクリックすると、テキストビューの(x1、y1)ポイントが取得され、画像をクリックすると、画像ビューの(x2、y2)位置が取得されます。 この値をDrawingクラスに渡して、線を描画しています。 しかし、毎回その描画は1本の線だけです。

誰か私にアイデアを教えてもらえますか?

これは私のメインクラスです:

public class MatchActivity extends Activity {
                    ArrayAdapter<String> listadapter;
                    float x1;
                    float y1;
                    float x2;
                    float y2;
                    @Override
                    public void onCreate(Bundle savedInstanceState) {
                        super.onCreate(savedInstanceState);
                        setContentView(R.layout.main);
                        String[] s1 = { "smiley1", "smiley2", "smiley3" };
                        ListView lv = (ListView) findViewById(R.id.text_list);
                        ArrayList<String> list = new ArrayList<String>();
                        list.addAll(Arrays.asList(s1));
                        listadapter = new ArrayAdapter<String>(this,R.layout.rowtext, s1); 
                        lv.setAdapter(listadapter);
                        GridView gv = (GridView) findViewById(R.id.image_list);
                        gv.setAdapter(new ImageAdapter(this));
                        lv.setOnItemClickListener(new OnItemClickListener() {
                          public void onItemClick(AdapterView<?> arg0, View v, int arg2,
                                    long arg3){                   
                               x1=v.getX();
                               y1=v.getY();
                               Log.d("list","text positions x1:"+x1+" y1:"+y1);
                           }
                        });

                    gv.setOnItemClickListener(new OnItemClickListener() {
                        public void onItemClick(AdapterView<?> arg0, View v, int arg2,
                            long arg3){
                                  DrawView draw=new DrawView(MatchActivity.this);
                          x2=v.getX();
                          y2=v.getY();
                              draw.position1.add(x1);
                              draw.position1.add(y1);
                          draw.position2.add( x2);
                              draw.position2.add(y2);
                          Log.d("list","image positions x2:"+x2+" y2:"+y2);
                     LinearLayout ll=LinearLayout)findViewById(R.id.draw_line);  
                                    ll.addView(draw);

                               }
                            });

                    }

                        }

これは、線を引くための私の描画クラスです。

 public class DrawView extends View {
                  Paint paint = new Paint();
                  private List<Float> position1=new ArrayList<Float>();
                  private List<Float> position2=new ArrayList<Float>();;

                    public DrawView(Context context) {
                        super(context);
                        invalidate();
                        Log.d("drawview","In DrawView class position1:"+position1+" position2:"+position2) ;

                    }

                    @Override
                    public void onDraw(Canvas canvas) {
                         super.onDraw(canvas);
                         Log.d("on draw","IN onDraw() position1:"+position1+" position2:"+position2);
                        assert position1.size() == position2.size();
                    for (int i = 0; i < position1.size(); i += 2) {
                        float x1 = position1.get(i);
                        float y1 = position1.get(i + 1);
                        float x2 = position2.get(i);
                        float y2 = position2.get(i + 1);
                                paint.setColor(Color.BLACK);
                        paint.setStrokeWidth(3);
                                canvas.drawLine(x1,y1, x2,y2, paint);
                        }
                    }

                }

私のレイアウトmain.xmlファイル:

<LinearLayout 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:gravity="center_horizontal">

    <ListView
        android:id="@+id/text_list"
        android:layout_width="150dp"
        android:layout_height="fill_parent" 
        />

    <LinearLayout
        android:id="@+id/draw_line"
        android:layout_width="150dp"
        android:layout_height="fill_parent"
        android:background="#cccccc" />

    <GridView
        android:id="@+id/image_list"
        android:layout_width="150dp"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:stretchMode="columnWidth"
        android:verticalSpacing="10dp"
        android:columnWidth="150dp"/>


</LinearLayout>

私のLogcatの詳細:

テキストと画像の初回選択:

10-19 10:42:23.672: D/Text list(653): Clicking on text co-ordinates are:0.0 ,151.0
10-19 10:42:25.831: D/Image list(653): Clicking on image co-ordinates are:0.0 ,320.0
10-19 10:42:25.861: D/onDraw()(653): In onDraw() co-ordinates of text position:[0.0, 151.0] image position:[0.0, 320.0]

テキストと画像の2回目の選択:

10-19 10:42:58.512: D/Text list(653): Clicking on text co-ordinates are:0.0 ,302.0
10-19 10:43:00.144: D/Image list(653): Clicking on image co-ordinates are:0.0 ,0.0
10-19 10:43:00.303: D/onDraw()(653): In onDraw() co-ordinates of text position:[0.0, 151.0] image position:[0.0, 320.0]

テキストと画像の3回目の選択:

10-19 10:43:24.962: D/Text list(653): Clicking on text co-ordinates are:0.0 ,0.0
10-19 10:43:26.144: D/Image list(653): Clicking on image co-ordinates are:0.0 ,320.0
10-19 10:43:26.261: D/onDraw()(653): In onDraw() co-ordinates of text position:[0.0, 151.0] image position:[0.0, 320.0]

前もって感謝します 。

4

1 に答える 1

1

私はおそらくこれをカスタムコンポーネントで行います。ここでは、画像とテキストもレンダリングします。タッチを検出し、簡単なアルゴリズムを使用して、ヒットしたものを検出します(たとえば、各コンポーネントの高さで割ってどの線を取得し、タッチがヒットした側(左または右)を確認するためにテストします。おそらく気にする必要はありません。テキストと画像の境界を使用します。連結成分をリストに格納し、連結成分を指定して線の座標を計算します(タッチの検出とほぼ同じですが、逆になります)。

コードに関するいくつかの小さなコメント:メソッド内のメソッドにローカルな変数を保持し、Floatとfloatは自動的に変換され、クラスとしてより適切に表現されるオブジェクトを表すために配列を使用しないでください(p1.getX()の方が読みやすいp1.get(0)より)。

編集:ポイント間に線を引きたいだけの場合は、次のようにすることができます。

public void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  Log.d("on draw","on draw position1:"+position1+" position2:"+position2);

  assert position1.size() == position2.size();

  for (int i = 0; i < position1.size(); i += 2) {
     float x1=position1.get(i);
     float y1=position1.get(i+1);
     float x2=position2.get(i);
     float y2=position2.get(i+1);
     paint.setColor(Color.BLACK);
     paint.setStrokeWidth(3);
     canvas.drawLine(x1,y1+75, x2+300,y2, paint);
  }
}

ただし、ユーザーがコンポーネントを正しい順序でクリックしていることを確認する必要があります。同じ列を2回クリックすると、問題が発生します。クリックハンドラーでそれを解決する必要があります。これに関する最大の問題は、ハードコードされた定数75と300です。レイアウトが表示されないため、そこで何をしたかわかりませんが、1つのコンポーネントを使用した方がよいと確信しています。すべてを描画します。

編集:書き直し

これは、MatchActivityのクリーンアップバージョンです(ただし、テストされていません)。

package com.example.mediakey;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import android.widget.LinearLayout;
import android.widget.ListView;

public class MatchActivity extends Activity {
    ArrayAdapter<String> listadapter;
    DrawView draw;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        String[] s1 = { "smiley1", "smiley2", "smiley3" };
        ListView lv = (ListView) findViewById(R.id.text_list);
        ArrayList<String> list = new ArrayList<String>();
        list.addAll(Arrays.asList(s1));
        listadapter = new ArrayAdapter<String>(this, R.layout.rowtext, s1);
        lv.setAdapter(listadapter);
        GridView gv = (GridView) findViewById(R.id.image_list);
        gv.setAdapter(new ImageAdapter(this));

        // This should be done in the layout xml
        // I moved it here to do it only once not for every click
        // I don't know how your layout is defined but it seems as this should
        //   be the parent component of the text and image views and it's not.
        //   If it works like this I don't think you should bother with it.
        //   Otherwise post your layout file.
        LinearLayout ll= (LinearLayout) findViewById(R.id.draw_line);
        draw = new DrawView(this);
        ll.addView(draw);

        lv.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> arg0, View v, int arg2, long arg3){
                float x1 = v.getX();
                float y1 = v.getY();
                draw.addSourcePoint(x1, y1);
                Log.d("list","text positions x1:"+x1+" y1:"+y1);
            }
        });

        gv.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> arg0, View v, int arg2, long arg3){
                float x2 = v.getX();
                float y2 = v.getY();
                draw.addDestinationPoint(x2, y2);
                Log.d("list","image positions x2:"+x2+" y2:"+y2);
            }
        });

    }
}

そして、これが書き直されたDrawViewです(これもテストされていません):

package com.example.mediakey;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.Log;
import android.view.View;

public class DrawView extends View {
    Paint paint = new Paint();
    private List<Float> position1=new ArrayList<Float>();
    private List<Float> position2=new ArrayList<Float>();;

    public DrawView(Context context) {
        super(context);
        invalidate();
        Log.d("drawview","In DrawView class position1:"+position1+" position2:"+position2) ;
    }

    @Override
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Log.d("on draw","IN onDraw() position1:"+position1+" position2:"+position2);

        assert position1.size() == position2.size();

        for (int i = 0; i < position1.size(); i += 2) {
            float x1 = position1.get(i);
            float y1 = position1.get(i + 1);
            float x2 = position2.get(i);
            float y2 = position2.get(i + 1);
            paint.setColor(Color.BLACK);
            paint.setStrokeWidth(3);
            canvas.drawLine(x1,y1, x2,y2, paint);
        }
    }

    public void addSourcePoint(float x1, float y1) {
        position1.add(x1);
        position1.add(y1);
    }

    public void addDestinationPoint(float x2, float y2) {
        position2.add(x2);
        position2.add(y2);
        invalidate();
    }
}

次に、最後に呼び出されたadd * Pointsメソッドを確認する必要があります。同じメソッドが連続して2回呼び出された場合は、それを処理する必要があります。これを自分で解決する必要があります。

于 2012-10-16T22:10:14.867 に答える