简体   繁体   English

将变量从参数中的一个类发送到另一个类。 简单错误

[英]Send a variable from one class in a parameter to another class. Simple error

The variable I want to send to the other class is int position. 我想发送给另一个类的变量是int position。 It is in the parameter for the instantiateItem method. 它位于InstantiateItem方法的参数中。 This basically indicates what position the swipe layout is at. 这基本上表明了滑动布局的位置。

Now the variable position is only avaliable inside the onClick method. 现在,变量位置仅在onClick方法中可用。 As soon as it's outside the method it's always 0. Will put examples in the code. 一旦在方法之外,它就始终为0。将示例放入代码中。

public class Csa{

private int getposition; 

public Object instantiateItem(ViewGroup container, int position) {
    layoutInflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View item_view = layoutInflater.inflate(R.layout.swipe_layout, container, false);
    imageView = (ImageView) item_view.findViewById(R.id.image_view);
    TextView textView = (TextView) item_view.findViewById(R.id.image_count);
    imageView.setImageResource(image_resources[position]);
    textView.setText(names[position]);
    container.addView(item_view);

    imageView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            switch(position){
             getposition = position;        
             case 1:
                 System.out.println(position); //Outputs 1. Correct.
                 Log.d("Exercise", "Deadlift!");
                 Intent intent1 = new Intent(CustomSwipeAdapter.this.ctx, AnalysisPage.class);
                 CustomSwipeAdapter.this.ctx.startActivity(intent1);
                 break;
             case 2:
                 getposition = position; 
                 System.out.println(position); // Outputs 2. Correct.
                 System.out.println(getposition()); // Outputs 2. Correct.
                 Log.d("Exercise", "Squats");
                 Intent intent2 = new Intent(CustomSwipeAdapter.this.ctx, AnalysisPage.class);
                 CustomSwipeAdapter.this.ctx.startActivity(intent2);
                 break;
         }


            }

    });

    return item_view;
}

   public int getposition() {
    return getposition;
}



 public class AnotherClass{
 Csa chooser = new Csa(this);
 private int command = chooser.getPosition();//Debugged. This is 0 always 0. Should be 1/2. Wrong.

 public static void main(String args[]){
 System.out.println(command);// Always prints out 0.

The variables inside the case/switches are always right. 机箱/开关内的变量始终正确。 However if I'm making a global variable or even I assign the position variable to another variable, 0 is always the output. 但是,如果我正在创建全局变量,或者甚至将位置变量分配给另一个变量,则输出始终为0。 (See example in code). (请参见代码示例)。

Ultimately, I want the position variable to be in another class but the output is always 0. I have tried Getter/Setter methods and they still don't work. 最终,我希望position变量位于另一个类中,但输出始终为0。我尝试了Getter / Setter方法,但它们仍然不起作用。

An anonymous class can only access final variables of the enclosing class. 匿名类只能访问封闭类的最终变量。 In order to get around this, add the following class (in a separate file) to your project: 为了解决此问题,请将以下类(在单独的文件中)添加到您的项目中:

public class ValueHolder<T> {

    private T value = null;

    public ValueHolder() {
        setValue(null);
    }

    public ValueHolder(final T newValue) {
        setValue(newValue);
    }

    public T getValue() {
        return value;
    }

    public void setValue(final T newValue) {
        value = newValue;
    }

}

Then at the top of your code, replace int x = 0 with: 然后在代码的顶部,将int x = 0替换为:

final ValueHolder<Integer> xHolder = new ValueHolder<Integer>(0);

And at each location in your anonymous class: 在您的匿名班级的每个位置:

case 0:
     System.out.println(position); // Prints out 0 Correct
     xHolder.setValue(position);
...

case 1:
     System.out.println(position); // Prints out 1 Correct
     xHolder.setValue(position);
...

Then later when you want to use the value stored in the holder: 然后,当您想使用存储在持有人中的值时:

int storedX = xHolder.getValue();

EDIT: adding an observer 编辑:添加一个观察者

Create the following interface: 创建以下界面:

public interface OptionObserver {
    void notifyOptionChange(final int option);
}

Then make the other class that you need to send the value to, implement this interface. 然后使您需要将值发送到的另一个类,实现此接口。

Your CustomWipeAdapter should then have an attribute and a setter: 然后,您的CustomWipeAdapter应该具有一个属性和一个setter:

OptionObserver optionObserver = null;

public void setOptionObserver(OptionObserver observer) {
    optionObserver = observer;
}

Then during initialisation, you call setOptionObserver() passing a reference to the instance of your other class. 然后在初始化期间,您调用setOptionObserver() ,将对其他类的实例的引用传递给它。

And in your CustomWipeAdapter: 在您的CustomWipeAdapter中:

case 1:
    System.out.println(position); //Outputs 1. Correct.
    if(optionObserver != null) {
        optionObserver.notifyOptionChange(position);
    }
...

What you are practically doing, is declaring a Java anonymous class inside your listener, implementing the onClick method that will be called. 实际上,您正在做的是在侦听器中声明一个Java匿名类,实现将被调用的onClick方法。 This enclosing class has a different scope by its outter class (they are not related by inheritance or friendship). 此封闭类的外部类具有不同的范围(它们与继承或友谊无关)。

Now, the onClick method will be called asynchronously, as onClick is a callback, ie a method called when an event occurs that its containing class instance is registered to. 现在, onClick方法将被异步调用,因为onClick是一个回调,即在发生其包含其类实例的事件注册时调用的方法。

When the event occurs, the callback will change the values of x, as it is visible beside its scope, but not before the event occurs, and not in a synchronous way. 当事件发生时,回调将更改x的值,因为x的值在其作用域旁边可见,但不在事件发生之前发生,并且不采用同步方式。

Think it like this in a simple example: 在一个简单的示例中这样想:

-Hello Jack, I hold an empty cofee cup. -你好杰克,我拿着一个空的咖啡杯。 (your x var declared in outter class) (您在外部类中声明的x var)

-Hello Joe, When the cofee maker is ready, I want you to fill your cofee cup (when an event occurs, change the value of x). -Hello Joe,当咖啡壶准备就绪时,我希望您填充咖啡杯(发生事件时,更改x的值)。

-What does your cup contain now? -你的杯子现在装什么? (print x, before the event) (在活动开始前打印x)

-Nothing (0, logical). -什么都没有(0,逻辑)。

-No, no, wrong! -不,不,错!

-Hey, but the Coffee maker is not done yet. -嘿,但是咖啡壶还没做完。 I will fill it when the coffee maker is ready. 咖啡机准备好时,我将其装满。

What you should do is handle the data always after the event has occurred. 您应该做的是始终事件发生处理数据。 I suggest that you do not use a property of the outter class, instead create a method in the outter class that takes an argument (the variable you want to use) and the rest of your code, and make sure that this method will be invoked inside your callback. 我建议您不要使用outter类的属性,而是在outter类中创建一个接受参数(要使用的变量)和其余代码的方法,并确保将调用此方法在您的回调中。 For example: 例如:

public class CustomSwipeAdapter extends PagerAdapter {
    //Rest of code....
    public void NotifyWhenClickOccurs(int x){
      System.out.println(x);
      //Use x here.
    }


    imageView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            switch(position){
             case 0:
                 System.out.println(position); // Prints out 0 Correct
                 //Notify your outter class instance.
                 Notify(position);
                 Log.d("Exercise", "Dumbell Press");
                 Intent intent0 = new Intent(CustomSwipeAdapter.this.ctx, AnalysisPage.class);
                 CustomSwipeAdapter.this.ctx.startActivity(intent0);
                 break;
             //Rest of code.....
         }
    }
}

This is similar to saying: 这类似于说:

-(Joe) Jack, I will let you know when I fill my cup, so that you can drink my coffee. -(乔)杰克,当我加满杯子时,我会告诉你,以便你可以喝咖啡。

A great standardized way of doing this is the Observer design pattern, and you are doing something similar here, considering the outter class as an "observer" in a more draft and general way. 观察者设计模式是一种很好的标准化方法,在这里您正在做类似的事情,将外部类以更草拟和更通用的方式视为“观察者”。

Another thing you should consider is what you are doing inside your callback and notifying methods (what thread do they use? Can they perform changes to GUI/Dispatch thread from there?), but this is out of the scope of the question, just some food for thought. 您应该考虑的另一件事是您在回调和通知方法内部做的事情(它们使用什么线程?它们可以从那里对GUI / Dispatch线程进行更改吗?),但这超出了问题的范围,仅是一些思考的食物。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM