2012-10-11 38 views
2

我想创建应用程序,通过用线指向与适当的图像相匹配的文本。Android如何通过用文本和图像指向文字与图像匹配

我想创建的应用程序完全相同,其下面的图像所示:

I created List of text views and a grid view of images in between I have linear layout. When I click on text view I will get (x1,y1) points of text view and when I click on image I will get (x2,y2) positions of image view. I am passing this values to Drawing class to draw a line. But every time its drawing only one line.

任何一个可以请给我一个想法?

这是我的主类:

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详情:

F文本和图像的IRST时间选择:文字和图片的

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] 

第二次选择:文字和图片的

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] 

第三次选择:

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] 

在此先感谢。

+0

嗨Tobias Ritzau,感谢您的快速回复。我创建了文本视图列表和网格视图之间的图像我有线性布局。当我点击文本视图时,我将得到文本视图的(x1,y1)点,当我点击图像时,我将得到图像视图的(x2,y2)位置。我将这个值传递给Drawing类来绘制一条线。但是每次只绘制一条线。我附上我的代码。 – Shirisha

回答

1

我可能会在custom component中做到这一点,在那里你也渲染图像和文本。检测触摸,并使用一个简单的算法来检测它们所击中的内容(例如,除以每个组件的高度以获得哪条线,并测试触摸哪一侧(左侧或右侧)命中。您可能不必打扰将文本和图像边界存储在一起,将连接的组件存储在一个列表中,并计算给定连接组件的线的坐标(或多或少与用于检测触摸但是反转相同)

对您的代码的一些小评论:Keep方法中方法的局部变量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); 
    } 
} 

但现在你必须确保用户点击以正确的顺序组件。如果您在同一列上单击两次,则会出现问题。你将不得不在点击处理程序中解决这个问题。我遇到的最大问题是硬编码常量75和300.我没有看到你的布局,所以我不知道你在那里做了什么,但我确信你会更好地使用一个组件吸取一切。

编辑:重写

这是你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方法最后调用,如果同一行在连续调用两次,您需要处理这一点。你需要解决这个问题。

+0

感谢您的回复Tobias,我并没有完全明白你指的是什么。对于这个新手来说,一些代码对我来说有助于推进并实现这一点。我希望用户在运行时将文本与图像进行匹配,用户单击文本,然后在图像上应该在他点击的视图之间绘制一条线。在我的代码画布中,完全按照我想要的方式画出一条线。但它仅适用于单个选定的文本和图像。第二次它没有画任何线。 :-( – Shirisha

+0

感谢您的代码,但在这里我的问题是我将文本和图像位置的坐标传递给DrawView类,我将它存储在position1和position2中,对于每个选择的文本和图像,它调用DrawView构造函数并更改值每次onDraw()都会为绘制线和onDraw()绘制第一个选择点。第一次选择后值不会改变。请帮助我,否则有其他方法可以实现这一点。 – Shirisha

+0

因为DrawView有一个引用到第一个列表。不要在onClick中创建新的列表并且继续玩。我试图给你另一个提议。我仍然建议,但是为了让你去也许最好是让你的代码更多的功能 –