如何在布局中的视图之间传输数据

Posted

技术标签:

【中文标题】如何在布局中的视图之间传输数据【英文标题】:How to transfer data between Views in a Layout 【发布时间】:2011-04-17 16:55:38 【问题描述】:

我无法找到以下问题的答案:

如何从视图 A 获取数据到视图 B,视图 A 和视图 B 在同一个 LinearLayout 中?这甚至可能吗?我需要开始使用线程吗?

我猜我一直找不到正确的搜索词组,我可能不是第一个想要这样做的人,但我找不到它:(

下面是我现在用来创建视图的内容。在 TargetTrainer(扩展 View)中,我让用户提供一些输入,并且我希望能够在 TextView 中向用户提供反馈。例如,我将如何在 TextView 中显示 TargetTrainer 的 onTouchEvent 的坐标?

下面是我的程序的剪辑/简化版本。

public void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    LinearLayout linear;
    linear = new LinearLayout(this);

    linear.setOrientation(LinearLayout.VERTICAL);
    TextView text = new TextView(this);
    text.setText("Test");
    linear.addView(text);

    Display display = getWindowManager().getDefaultDisplay(); 
    int width = display.getWidth();
    int height = display.getHeight();

    TargetTrainer t = new TargetTrainer(this, width, height);
    linear.addView(t);
    setContentView(linear);


【问题讨论】:

我想我可能需要对上下文做一些事情,因为我们需要将它传递给视图,但这对我来说也很不清楚 【参考方案1】:

从 sn-p 中可以看出,您已经在构造函数 new TargetTrainer(this, width, height) 中传递了 Context。假设您提供的代码来自名为BaseActivity 的活动,在TargetTrainer 构造函数中创建对BaseActivity 的引用并从TargetTrainer 调用更新方法。

public TargetTrainer extends View 

    ....
    BaseActivity mBaseActivity = null;


    public MyView(Context context, int width, int height) 
    ....
    mBaseActivity = (BaseACtivity)context;
    ....        
    

    ....

    private void update(String text)
    
        mBaseActivity.updateTextView(text);
    

BaseActivity 中创建updateTextView

public void updateTextView(String updateText) 
    text.setText(updateText);

【讨论】:

是的,成功了!我有一种预感,整个上下文的东西对某些东西有好处,但不知道是什么:) 这是我第一次做 UI,我习惯于将输入/输出转储到文件中 - 有很多东西要学;) 【参考方案2】:

你应该设置那个TextView的id,在你的TargetTrainer中监听触摸事件,当一个发生时,你使用

final TextView tv = (TextView)TargetTrainer.this.findViewById(R.id.myTextView);
tv.setText(touchEvent.toString());

就是这样。

更新

如果您从 xml 源构建主布局,那会更简洁。 您需要在 /res/layout 中创建一个新的布局 xml,它看起来就像您在 onCreate 方法中创建的那样:

res/layout/main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_
    android:layout_>
    <TextView android:id="@+id/myTextView" android:text="Test"
        android:layout_ android:layout_ />
    <!-- change the your.package part to match the package declaration 
        of your TargetTrainer class -->
    <your.package.TargetTrainer android:id="@+id/myTargetTrainer"
        android:layout_ android:layout_ />
</LinearLayout>

这样,一个新条目将被放置在您的 R 类的静态 layout 类中,名称为 main。 可以通过R.layout.main引用。

请注意,在此 xml 中,您为两者都定义了 id 属性

您的 TextView:myTextView,以及 您的 TargetTrainer: 'myTargetTrainer'。

xml 标记内的@+id 表示您正在创建一个名称在“/”符号后的新 id。 这还将使用您提供的名称在您的 R 类的静态 id 类中创建新成员:myTextViewmyTargetTrainer,从现在开始可以从代码中的任何位置访问它们。

如果您已构建此 xml,您的 onCreate 方法将如下所示:

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)

    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    // attach the OnTouchListener to your TargetTrainer view:
    (TargetTrainer)findViewById(R.id.myTargetTrainer).setOnTouchListener(this);

您还必须扩展您的主要活动类以实现View.OnTouchListener 接口,并在您的类末尾添加必要的方法:

@Override
public boolean onTouch(View view, MotionEvent event)

    //note, that here the view parameter is the view the touch event has been dispatched to
    final TextView tv = (TextView)findViewById(R.id.myTextView);
    tv.setText(event.toString());
    return true; //or false, if you are dealing further with this event in parent classes

【讨论】:

谢谢!虽然还没有为我工作。我可以通过分配一个数字来手动设置 ID 对吗?我不太了解 R.layout.textview 部分。无论如何,如果我为 textview 分配一个随机数(6564),并将最终 TextView tv = (TextView)TargetTrainer.this.findViewById(6564);我在 tv.setText(touchEvent.toString()); 得到一个空指针异常; (这不是 rouchevent:tv.setText("test"); 也失败了) 我会在几分钟内更新答案,并分享一个干净的 R 和布局使用示例。 我正在使用你现在所说的,我正在理解这些东西是如何工作的,它更有意义,就像你说的那样更干净。我现在用 xml 完成了所有布局,这好多了!主要问题是将屏幕的宽度和高度传递给 TargetTrainer,但是使用 Youri 教我的方法,我现在这样做: mTrainingMode = (TrainingMode)context; Display display = mTrainingMode.getWindowManager().getDefaultDisplay 从那里我可以再次获得屏幕宽度和高度,我需要调整drawable的大小

以上是关于如何在布局中的视图之间传输数据的主要内容,如果未能解决你的问题,请参考以下文章

如何在父视图控制器和子视图控制器之间传输数据

如何在相对布局中的布局之间居中

在 Amazon Redshift 中的表之间传输数据

使用 iOS 7 中的动态类型,我如何考虑更高级的布局问题,例如标签/视图之间的间距?

如何使用自动布局在两个子视图控制器之间移动?

MVC 在视图之间传输数据