【问题标题】:How to get a method called with different parameters?如何获取使用不同参数调用的方法?
【发布时间】:2017-04-16 03:49:12
【问题描述】:

我从数据库中获取 3 个String 值,然后将其转换为Long,然后计算差异,然后将计算出的Long 值作为参数放入方法中。我正在使用FastAdapter

filterRequests(List <Long> l)MainActivity 中的一个方法,它根据长l 执行过滤请求/内容的逻辑。

整个适配器:

public class GRModelClass extends AbstractItem<GRModelClass, GRClass.ViewHolder>{

    private static final ViewHolderFactory<? extends ViewHolder> FACTORY = new ItemFactory();

    String postedBy, postedTime, currentLat, currentLng, utcFormatDateTime, userEmail, userID;
    String startDateTimeInEpoch, endDateTimeInEpoch;
    DatabaseReference primaryDBKey;
    long ms;
    String itemID;

    public GRModelClass(){}

    public GRModelClass(String postedBy, String postedTime, String currentLat, String currentLng, String utcFormatDateTime, String userEmail, String userID, String startDateTimeInEpoch, String endDateTimeInEpoch, DatabaseReference primaryDBKey) {
        this.postedBy = " " + postedBy;
        this.postedTime = postedTime;
        this.currentLat = currentLat;
        this.currentLng = currentLng;
        this.utcFormatDateTime = utcFormatDateTime;
        this.userEmail = userEmail;
        this.userID = userID;
        this.startDateTimeInEpoch = startDateTimeInEpoch;
        this.endDateTimeInEpoch = endDateTimeInEpoch;
        this.primaryDBKey = primaryDBKey;
    }

    @Exclude
    public Map<String, Object> toMap() {
        HashMap<String, Object> result = new HashMap<>();
        result.put("pBy", postedBy);
        result.put("cLat", currentLat);
        result.put("cLng", currentLng);
        result.put("utcFormatDateTime", utcFormatDateTime);
        result.put("userEmail", userEmail);
        result.put("userID", userID);
        result.put("startDateTime", startDateTimeInEpoch);
        result.put("endDateTime", endDateTimeInEpoch);

        return result;
    }


    @Override
    public int getType() {
        return R.id.recycler_view;
    }

    @Override
    public int getLayoutRes() {
        return R.layout.sr_layout;
    }

    @Override
    public void bindView(final ViewHolder holder, List list) {
        super.bindView(holder, list);

        holder.postedBy.setText(postedBy);
        holder.postedBy.setTypeface(null, Typeface.BOLD);
        holder.startDateTimeInEpoch.setText(startDateTimeInEpoch);
        holder.startDateTimeInEpoch.setVisibility(View.INVISIBLE);
        holder.endDateTimeInEpoch.setText(endDateTimeInEpoch);
        holder.endDateTimeInEpoch.setVisibility(View.INVISIBLE);

        MainActivity.filterButton.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem menuItem) {
                holder.geoQuery = holder.geoFireReference.queryAtLocation(new GeoLocation(holder.currentLatDouble, holder.currentLngDouble), 5);

            holder.geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() {
                @Override
                public void onKeyEntered(String key, GeoLocation location) {
                    primaryDBKey.child(key).child("startDateTimeInEpoch").addListenerForSingleValueEvent(new ValueEventListener() {
                        @Override
                        public void onDataChange(DataSnapshot dataSnapshot) {
                            if (dataSnapshot.getValue() != null) {
                                holder.startTimeDateInEpochLong2 = Long.parseLong(dataSnapshot.getValue().toString());
                                holder.now = System.currentTimeMillis() / 1000;
                                holder.diffNowsdtel.add(holder.startTimeDateInEpochLong2 - holder.now);
                                Log.d("log1", String.valueOf(holder.diffNowsdtel));

                                Handler handler = new Handler();
                                handler.postDelayed(new Runnable() {
                                    @Override
                                    public void run() {
                                        if(holder.mContext instanceof MainActivity){
                                            ((MainActivity)holder.mContext).filterRequests(holder.diffNowsdtel);
                                            Log.d("log2", String.valueOf(holder.diffNowsdtel));
                                        }
                                    }
                                }, 1500);
                            }
                        }

                        @Override
                        public void onCancelled(DatabaseError databaseError) {

                        }
                    });
                }

                @Override
                public void onKeyExited(String key) {

                }

                @Override
                public void onKeyMoved(String key, GeoLocation location) {

                }

                @Override
                public void onGeoQueryReady() {

                }

                @Override
                public void onGeoQueryError(DatabaseError error) {

                }
            });
                return true;
            }
        });

    }

    /**
     * our ItemFactory implementation which creates the ViewHolder for our adapter.
     * It is highly recommended to implement a ViewHolderFactory as it is 0-1ms faster for ViewHolder creation,
     * and it is also many many timesa more efficient if you define custom listeners on views within your item.
     */
    protected static class ItemFactory implements ViewHolderFactory<ViewHolder> {
        public ViewHolder create(View v) {
            return new ViewHolder(v);
        }
    }

    /**
     * return our ViewHolderFactory implementation here
     *
     * @return
     */
    @Override
    public ViewHolderFactory<? extends ViewHolder> getFactory() {
        return FACTORY;
    }


    // Manually create the ViewHolder class
    protected static class ViewHolder extends RecyclerView.ViewHolder {

        TextView postedBy, userID, currentLt, currentLn, requestID, postedFrom;
        TextView startDateTimeInEpoch, endDateTimeInEpoch, diffNowsdtelTV;
        LinearLayout linearLayout;
        long difference, differenceCurrentStartTime, handlerGap;
        long startTimeDateInEpochLong2;
        public static long now;
        List<Long> diffNowsdtel;
        Context mContext;
        DatabaseReference firebaseDatabase;
        GeoFire geoFireReference;
        GeoQuery geoQuery;


        public ViewHolder(final View itemView) {
            super(itemView);

            postedBy = (TextView) itemView.findViewById(R.id.postedBy);
            startDateTimeInEpoch = (TextView) itemView.findViewById(R.id.startTimeDateInEpoch);
            endDateTimeInEpoch = (TextView) itemView.findViewById(R.id.endTimeDateInEpoch);
            diffNowsdtelTV = (TextView) itemView.findViewById(R.id.diffNowsdtelTV);

            this.mContext = itemView.getContext();

        private boolean isNetworkAvailable() {
            ConnectivityManager connectivityManager
                    = (ConnectivityManager) itemView.getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
            return activeNetworkInfo != null && activeNetworkInfo.isConnected();
        }
    }
}

问题是,当我记录 log1 时,我得到了 Logcat 中显示的所有 3 个值,但是当我记录 log2 时,只计算了最后一个值值正在显示,这就是调用 filterRequests(Long l) 时使用的值。

更新 - 更新适配器代码后,log1log2 现在显示如下:

 D/log1: [2197]
 D/log1: [2197, -1007]
 D/log1: [2197, -1007, 4003]

 D/log2: [2197, -1007, 4003]

filterRequests() 方法是完成基于时间过滤内容的逻辑的方法。 filterRequests() 中的参数是 holder.diffNowsdtel,它现在有 3 个 long 值,并且应该基于它执行逻辑.. 如果长值是 &lt;=900 具有长值 @987654343 的内容应该显示@,当long值为&gt;900时,应该显示长值为21974003的内容。

代码如下:

public void filterRequests(final List<Long> l) {

    final int size = l.size();

            Log.d("lng", String.valueOf(l));

                    if (isNetworkAvailable()) {
                        if (chkBoxLiveRqsts.isChecked()) {



                                    firebaseDatabase.child(key).addValueEventListener(new ValueEventListener() {
                                        @Override
                                        public void onDataChange(DataSnapshot dataSnapshot) {
                                            if (dataSnapshot.getValue() != null) {
                                                for (int i = 0; i < size; i++){
                                                    if (l.get(i) <= 900) {
                                                    ...       
                                                    } else {
                                                    }
                                                }
                                                progressDialogAdding.dismiss();
                                            } else {
                                            }
                                        }

                                        @Override
                                        public void onCancelled(DatabaseError databaseError) {
                                        }
                                    });
                                }

                                ...
                            });
                        } else if (chkBoxSFLRqsts.isChecked()) {
                            fastItemAdapter.clear();
                            firebaseDatabase.child(key).addValueEventListener(new ValueEventListener() {
                                        @Override
                                        public void onDataChange(DataSnapshot dataSnapshot) {
                                            if (dataSnapshot.getValue() != null) {
                                                for (int i = 0; i < size; i++) {
                                                    if (l.get(i) > 900) {
                                                        ...

                                                    } else {
                                                    }
                                                }
                                                progressDialogAdding.dismiss();
                                            } else {
                                            }
                                        }

                                        @Override
                                        public void onCancelled(DatabaseError databaseError) {
                                        }
                                    });
                                }
                                ...
                        } 
                    } else {
                        Snackbar snackbar = Snackbar
                                .make(coordinatorLayout, "No internet connection", Snackbar.LENGTH_SHORT);
                        snackbar.show();
                        progressDialogAdding.dismiss();
                    }
                }
            });
            dialog = builder.create();
        dialog.show();
}

lng的日志值:

D/lng: [2197, -1007, 4003]

我想要的filterRequests(Long l) 方法应该使用holder.diffNowsdtelTV.getText().toString() 的所有值并使用它们执行逻辑。

对于含糊不清的问题,我深表歉意。请帮我解决这个问题!

【问题讨论】:

  • 这里有一些minimal reproducible example 怎么样?这似乎是一个简单的问题......
  • @AxelH 你这是什么意思,兄弟?
  • 您包含的代码量很多。此外,正如 AxelH 所说,这听起来像是一个简单的问题。如果您可以删除所有不必要的代码并包含所需的代码,那么其他人回答您的问题会很有帮助。此外,还不清楚您在filterRequests(..) 中要做什么。阅读他提供的链接
  • @RafiduzzamanSonnet 我已尽我所能编辑...请看一下
  • 首先,您说的是MainActivitiy.filterRequest(Long l),但我只能找到MainActivitiy.filterRequest(final List&lt;Long&gt; l),那么,如果我翻译您想要的方法,我理解的是What are captured variables in Java Local Classes。这可以在 5line 的示例中恢复。 PS:请不要兄弟我;)

标签: java android methods android-context instanceof


【解决方案1】:

你在做什么

在您的 ViewHolder diffNowsdtel 被声明为 long (保存最新值),每当您记录 log1 Logger 显示(来自diffNowsdtel 的最新值,因此您的日志显示不同的值,因为bindView 会在您更新行或完整数据集时多次调用)

D/log1: -22136
D/log1: -22403
D/log1: -25094

onMenuItemClick 内部,您直接从您的TextView 获取值,现在是-25094,这就是为什么您的TextView 中只有一个值并且日志显示

D/log2: -25094

你应该做什么

使用holder.diffNowsdtelTV.setTag(your database key or row_id) 设置标签并在您的onMenuItemClick 中使用您的标签

Object someTagName = (Object) holder.diffNowsdtelTV.getTag();

现在使用存储在someTagName 中的值从数据库中获取您的 3 个String 值,然后进行计算。

编辑

实际上,您需要 3 个值来进行计算,而在您当前的逻辑中,您只有最新的值存储在 diffNowsdtel 中。所以现在你需要一个逻辑来将你的值存储在某个地方和内部onMenuItemClick 使用它们但是如果你要保存你的值你必须将你的diffNowsdtel 更改为long[]List&lt;Long&gt; 并保存你的每个值在每个需要一些逻辑的 bindView 调用中,最简单的方法是传递你唯一的数据库列,比如主键并将其保存在你的 GRModelClass

String primaryDbKey;

public GRModelClass(String primaryDbKey, ...) {
    this.primaryDbKey = primaryDbKey;
    ....
}

在您的 onMenuItemClick 中,使用 primaryDbKey 从您的数据库表(您正在其他地方执行)获取您的 3 个 String 值,然后进行计算。


编辑

您使用Long 创建了一个列表,ListLong 都不是原始数据类型。 在您的问题中,您正在比较原始数据类型和非原始数据类型,比较器的两侧应该是相同的数据类型。

你在做什么:

if (l.get(i) <= 900)

这里l.get(i) 返回一个Long 值,其中900 是整数值。

你应该做什么:

只需通过 900L 将您的 l.get(i)Long 进行比较

if (l.get(i) <= 900L)

或者

if (l.get(i) > 900L)

【讨论】:

  • 嘿...感谢您的回答。我仍然对 What you should do 部分感到困惑。请写一些代码或更清楚地解释。请?再次感谢。
  • 基于您的“编辑”,我尝试了它,并更新了问题中的适配器和logcatlog2 现在也显示 3 个值,就像 log1 一样,但所有 3 个值都相同。
  • 这是因为你还在diffNowsdtel中使用onDataChange,即-29601。您应该根据您的 3 个String 值计算结果并使用它们。如果这样做,请不要将其值保存在变量中,否则您将在变量中保存最新值或创建 long[]List&lt;Long&gt; 并在其中保存 3 个值
  • Salaam 兄弟...您刚刚编辑了我的一个问题。这就是我在您之前的评论之后尝试过的。 :(
  • com 在聊天中开始我们的讨论
【解决方案2】:

尝试在onBindView中设置初始化你想要的值

   Log.d("diffNowsdtel", holder.diffNowsdtelTV.getText().toString());
    final String val = holder.diffNowsdtelTV.getText().toString();

            MainActivity.filterButton.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
                @Override
                public boolean onMenuItemClick(MenuItem menuItem) {
                    if(holder.mContext instanceof MainActivity){
                        ((MainActivity)holder.mContext).filterRequests(Long.parseLong(val));
                        Log.d("diffNowsdtel2",val);
                    }
                    return true;
                }
            });

【讨论】:

  • 好的,那么您可以将整个适配器代码发布到问题中吗?
  • 我已经编辑了我的解决方案。试试看会发生什么
  • 在第一个日志之前设置 val,在两个日志中都使用,有什么变化吗?
  • @While-E 不。不用找了。 log1 打印了所有 3 个值,而 log2 仅打印了最后一个计算值。请参阅已编辑的问题。
  • @While-E 我也尝试过这种方法:stackoverflow.com/a/17837183/6144372,但它也只显示了最后计算的值:(
【解决方案3】:

您在 MainActivity 中有一个名为 filterButton 的静态定义对象。每次为新视图调用 bindView 时,它都会替换该按钮的菜单项侦听器。因此,当您单击该菜单项时,它只会调用您为调用 bindView 的最后一项设置的处理程序。这就是为什么在按下过滤器按钮时您只会看到一个日志条目的原因。

【讨论】:

  • 请告诉我如何让该功能开始工作?
  • 您可以尝试在 Activity 中创建过滤器按钮时设置项目单击侦听器,而不是在 bindView 中。侦听器可以获取列表中的所有项目并循环访问它们,从而为每个项目调用 filterRequests。这样,每次您单击按钮时,监听器都会为您的所有项目调用 filterRequests,您应该会收到 3 条日志消息。
  • 但是我必须静态设置holder.diffNowsdtelTV.getText().toString() 以将其作为参数传递给filterRequests() 并从MainActivity 调用它。这将再次仅显示/仅显示 holder.diffNowsdtelTV.getText().toString() 的最后计算值。 ://
猜你喜欢
  • 2010-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-12
  • 1970-01-01
  • 1970-01-01
  • 2021-06-15
相关资源
最近更新 更多