【问题标题】:How to pass an Activity reference to my own component如何将 Activity 引用传递给我自己的组件
【发布时间】:2012-05-07 09:03:08
【问题描述】:

我创建了一个日期时间组件,但它是自动构建的(我在 XML 布局中拥有它,我不想手动创建它)但我需要传递对 Activity 的引用才能创建对话框。我怎样才能做到这一点?我在findViewById 之后尝试了一个二传手,但这不是一个好的解决方案...

public class DateTimeComponent extends RelativeLayout {

    private Activity activity;

    public DateComponent(Context context, AttributeSet attributeSet) {
        super(context, attributeSet);
        // rest ommited
        initFields();
    }

    private void initFields() {
        dateEditText = (EditText) findViewById(R.id.dateEditText);
        dateEditText.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                activity.showDialog(DATE_PICKER_DIALOG);
            }
        });

        timeEditText = (EditText) findViewById(R.id.timeEditText);
        timeEditText.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                activity.showDialog(TIME_PICKER_DIALOG);
            }
        });
    }

    // rest ommited

    public Dialog getDatePickerDialog() {
        int year = selectedDateTime.get(YEAR);
        int month = selectedDateTime.get(MONTH);
        int day = selectedDateTime.get(DAY_OF_MONTH);
        return new DatePickerDialog(activity, onDateSetListener, year, month, day);
    }

    public Dialog getTimePickerDialog() {
        int hour = selectedDateTime.get(HOUR_OF_DAY);
        int minute = selectedDateTime.get(MINUTE);
        return new TimePickerDialog(activity, onTimeSetListener, hour, minute, true);
    }

    private final OnDateSetListener onDateSetListener = new OnDateSetListener() {
        @Override
        public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
            // do something
        }
    };

    private final OnTimeSetListener onTimeSetListener = new OnTimeSetListener() {
        @Override
        public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
            // do something
        }
    };

}

【问题讨论】:

  • 您可以通过构造函数将Activity/Context的引用传递给DateTimeComponent。
  • 您可以为此目的使用上下文
  • @Akki 上下文没有showDialog() 方法..

标签: java android dialog android-activity


【解决方案1】:

也许这对你有帮助:

选项 1:

public class DateTimeComponent extends RelativeLayout {
    private Activity activity;

    public DateTimeComponent(Activity act){
        activity = act;
    }

    public void someListener() {
        activity.showDialog(...);
    }

}

选项 2:

public class DateTimeComponent extends RelativeLayout {

    public void someListener(Activity act) {
        act.showDialog(...);
    }

}

选项 3:

...
    private Activity activity;

    public DateComponent(Context context, AttributeSet attributeSet) {
        super(context, attributeSet);

        activity = (Activity) getContext();

        // rest ommited
        initFields();
    }

...

【讨论】:

  • 但是我没有创建组件,我使用的是DateComponent component = (DateComponent) findViewById(R.id.dateComponent)
  • 我更新了我的问题...我也不能使用您的第二个选项,因为我在组件本身中初始化了所有侦听器。
  • 第三个选项有效。最后一个问题:我可以确定给定的上下文总是可以转换为Activity吗?
  • 是的,只要你从 Activity 中引用你的自定义类或视图,你就可以投射它
【解决方案2】:

两种方式——

  1. 创建一个接受 Context 参数的构造函数,并拥有一个 Context 类型的(私有?)类变量,您可以随时使用它。

  2. 为每个需要它的方法添加一个额外的上下文上下文参数。在某些情况下,您可能需要最终确定。

【讨论】:

    【解决方案3】:

    您的构造函数接收到的上下文是一个活动。因此,您可以将其投射到它上面。比如这样的

    MyActivity a = (MyActivity) getContext();
    

    附:您无需在自己的字段中存储活动:

    private Activity activity; // not needed
    

    里面已经存储了,可以通过http://developer.android.com/reference/android/view/View.html#getContext()获取

    证明

    自定义文本视图:

    public class MyTextView extends TextView {
    
    public MyTextView(Context context) {
        super(context);
        setText(Integer.toString(System.identityHashCode(context)));
    }
    
    public MyTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setText(Integer.toString(System.identityHashCode(context)));
    }
    
    
    }
    

    活动:

    public class ContextActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    
        TextView textView = (TextView) findViewById(R.id.textView);
    
        textView.setText( Integer.toString(System.identityHashCode(this)) );
    }
    }
    

    布局:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/textView" />
    
    <com.inthemoon.incubation.MyTextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"/>
    
    </LinearLayout>
    

    显示的代码相同。

    【讨论】:

    • 我很好奇 - The context your constructor receives IS an Activity 你对此有什么参考吗?
    • Activity 类是Context 的后代。我通过实验确定,在描述的简单情况下,该活动将传递给构造函数。我是新手,不能保证总是如此。 Context 有多种实现,因此在某些情况下可以使用它们。
    • 这不是证据。它仅表明这是 your 当前平台上的 current 实现。
    • 强调“我的平台”是指它不适用于你的平台?
    • 没有。我的意思是这不是证据。上下文是 Activity 是有道理的,但我没有看到对这种行为的要求。
    猜你喜欢
    • 1970-01-01
    • 2019-07-23
    • 2014-06-09
    • 2017-02-24
    • 1970-01-01
    • 2014-09-01
    • 1970-01-01
    • 2013-01-25
    • 1970-01-01
    相关资源
    最近更新 更多