john smith john smith - 1 month ago 19
Android Question

recyclerView.addOnItemTouchListener is not registering click

I am developing an app. This app initially downloads a package of GPS tagged images. Now, I on my home screen I show a list in recycler view. This is the list of names of the images in the package. They are listed in ascending order of the angle between mobile's y-axis and line joining mobile's origin and image's gps location. I am using

magnetometer
and
accelormeter
to find relevant angular data, and also getting GPS location from the mobile.

Now, whenever GPS location or sensor data is changed, I call
computeNearby()
which computes the order of items in the list. When I click an item, it opens another activity.

Here is my code



private void refreshRecyclerView() {
//setting the view of the NEARBY tab
// Log.v(LOGTAG, "going to set sorted interest points");
recyclerViewAdapter = new NearbyPointsRecyclerViewAdapter(sortedInterestPoints);
recyclerView.setAdapter(recyclerViewAdapter);
recyclerView.setItemAnimator(new DefaultItemAnimator());

// Log.v(LOGTAG, "Set sorted interest points and going to set OnItemTouchListener for recycler view");
recyclerView.addOnItemTouchListener(
new RecyclerViewOnItemClickListener(getActivity(), new RecyclerViewOnItemClickListener.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
Log.v(LOGTAG,"onItemClick registered in RecyclerViewOnItemClickListener");
RecyclerView.ViewHolder viewHolder = recyclerView.findViewHolderForLayoutPosition(position);
//getting the title of the clicked interest point
TextView textView = (TextView) viewHolder.itemView.findViewById(R.id.cardview_text);
String text = textView.getText().toString();

Intent intent_interest_point = new Intent(getActivity(), InterestPointActivity.class);
//passing the title of the clicked interest point to InterestPintActivity
intent_interest_point.putExtra("interest_point", text);
Log.v(LOGTAG,"InterestPointActivity is called");
startActivity(intent_interest_point);
}
})
);
}



@Override
public void onLocationChanged(Location location) {
currentLatitude = location.getLatitude();
currentLongitude = location.getLongitude();
//Toast.makeText(_context, currentLatitude + " WORKS " + currentLongitude + "", Toast.LENGTH_LONG).show();
computeNearby(currentLatitude, currentLongitude);
refreshRecyclerView();

}

@Override
public void onSensorChanged(SensorEvent event) {

if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
mGravity = event.values;

if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
mGeomagnetic = event.values;

if (mGravity != null && mGeomagnetic != null) {
float R[] = new float[9];
float I[] = new float[9];

if (SensorManager.getRotationMatrix(R, I, mGravity, mGeomagnetic)) {

// orientation contains azimuth, pitch and roll
float orientation[] = new float[3];
SensorManager.getOrientation(R, orientation);


oldAzimuth = azimuth;
azimuth = orientation[0];
pitch = orientation[1];
roll = orientation[2];
computeNearby(currentLatitude, currentLongitude);
}
}
}


public void computeNearby(Double currentLatitude, Double currentLongitude) {
//some sorting operations
for (int i=0; i<Math.min(TRUNCATION_LIMIT, interestPoints.size()); i++) {
interestPoint = interestPoints.get(finalThreeAngleIndices.get(i).second);
sortedInterestPoints.set(i, interestPoint);
}

refreshRecyclerView();

}





I use recyclerView() method to set the screen after sorting.

So basically it goes
onLocationChanged-->computeNearby-->refershRecylerView

and
onSensorChanged-->computeNearby-->refershRecylerView
.

But when I click any list view item, the click is not registered. When I call computeNearby from only onLocationChanged , the item click is registered and relevant activity is started. I think there is a problem with handling onSensorChanged. Please help me out.

Thanks for your time.

Answer

The problem here is, this angle of your's changes rapidly due to mobile's orientation. Sensor data relevant to it is changing rapidly and it is causing problem with the click event. Try to collect sensor data in certain intervals of time.

private static final int waitTimeInSeconds = 2;
        @Override
        public void onSensorChanged(SensorEvent event) {

            if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
                //other code
                  
                //Add the below code to your onSensorChanged()

                Calendar calendar = Calendar.getInstance();
                currentTime = calendar.getTimeInMillis();
                int timeDifference = (int) (currentTime - previousTime)/1000;
                Log.v(LOGTAG, "currentTime = "+currentTime+" previousTime = "+previousTime+" timeDifference = "+timeDifference);
                if(timeDifference > waitTimeInSeconds){
                    computeNearby(currentLatitude,currentLongitude);
                    previousTime = currentTime;
                }

            }
        }

Compared to the angle, GPS changes very slowly. But, if you are moving fast enough that GPS data is causing changes with your ordering of list items, you could add the above given code in onLocationChanged().