简体   繁体   English

Recyclerview onClick 仅在活动重启后工作

[英]Recyclerview onClick works only after an activity restart

I have a curious bug in my android app.我的 android 应用程序中有一个奇怪的错误。 I have a home fragment with a recyclerview adapter implementing an interface for click listener: on physical devices (not emulator) it works only after restarting the app or go to some other fragments and then returning to home fragment: after that, it works.我有一个带有 recyclerview 适配器的主片段,它实现了点击侦听器的接口:在物理设备(不是模拟器)上,它只有在重新启动应用程序或 go 到其他一些片段然后返回主片段后才能工作:之后,它就可以工作了。 The listener is implemented in other recycler view adapters in my app and works fine otherwise.侦听器在我的应用程序的其他回收器视图适配器中实现,否则工作正常。 I've tried every combination of clickable and focusable true/false in the CardViews which rappresent an item of my list, but nothing works.我已经在 CardViews 中尝试了可点击和可聚焦 true/false 的所有组合,它们表示我的列表中的一个项目,但没有任何效果。 Thanks for help!感谢帮助! (I have no errors while running the app) (运行应用程序时我没有错误)

EDIT I found the problem: the first time the app is launched, I ask locations permissions with the requestManifestPermissions() method shown in MainActivity: after the user accept or decline it, the OnClick in the adapter end to work.编辑我发现了问题:第一次启动应用程序时,我使用 MainActivity 中显示的 requestManifestPermissions() 方法询问位置权限:用户接受或拒绝后,适配器端的 OnClick 工作。 Any advice?有什么建议吗?

Adapter code:适配器代码:

public class HomeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

private String[] names = {
        "Ristoranti",
        "Bar",
        "Hotel",
        "Coffee",
        "Cinema",
        "Gelaterie",
        "Barbieri",
        "Pizzerie",
        "Banche",
        "Parking",
        "Ospedali",
        "Musei",
        "Supermercati",
        "Birrerie",
        "Farmacie"
};

private int[] images = {
        R.drawable.food,
        R.drawable.bar,
        R.drawable.hotel,
        R.drawable.coffee,
        R.drawable.cinema,
        R.drawable.icecream,
        R.drawable.barber,
        R.drawable.pizza,
        R.drawable.bank,
        R.drawable.parking,
        R.drawable.hospital,
        R.drawable.museum,
        R.drawable.supermarket,
        R.drawable.beer,
        R.drawable.pharma
};

private OnItemClickListener onClickListener;

public HomeAdapter() {

}

@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = 
    LayoutInflater.from(parent.getContext()).inflate(R.layout.cardview_home, 
    parent, false);
    return new MenuHolder(view, onClickListener);
}

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
    MenuHolder viewHolder = (MenuHolder) holder;
    viewHolder.displayView(names[position], images[position]);
}

@Override
public int getItemCount() {
    return names.length;
}

public void setOnClickListener(OnItemClickListener listener) {
    onClickListener = listener;
}

public String getItem(int position) {
    return names[position];
}

HomeFragment (which uses the adapter) code: HomeFragment(使用适配器)代码:

public class HomeFragment extends Fragment {

private static final int REQUEST_FINE_LOCATION = 1;
private boolean isLocationEnabled;

private RecyclerView recyclerView;

public HomeFragment() {

}

@Nullable
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
    View view = inflater.inflate(R.layout.fragment_recyclerview, container, false);
    isLocationEnabled = checkPermissions();
    recyclerView = view.findViewById(R.id.recyclerview_fav);
    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(requireContext());
    recyclerView.setLayoutManager(linearLayoutManager);
    recyclerView.setHasFixedSize(true);
    return view;
}

@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
    // Adapter
    HomeAdapter homeAdapter = new HomeAdapter();
    recyclerView.setAdapter(homeAdapter);
    homeAdapter.setOnClickListener((v, position) -> {
        if (isLocationEnabled) {
            NavController controller = Navigation.findNavController(requireActivity(), navHo
            Bundle bundle = new Bundle();
            bundle.putString("type", homeAdapter.getItem(position));
            bundle.putBoolean("nearby", true);
            controller.navigate(R.id.nearbyFragment, bundle);
        } else {
            requestPermissions();
        }
    });
}

MainActivity (I use single activity architecture) MainActivity(我使用单活动架构)

public class MainActivity extends AppCompatActivity {

private DrawerLayout drawerLayout;
private NavigationView navigationView;
private AppBarConfiguration appBarConfiguration;

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = findViewById(R.id.toolbar5);
    setSupportActionBar(toolbar);

    drawerLayout = findViewById(R.id.drawer);
    navigationView = findViewById(R.id.navigation_view);

    NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);

    appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph())
            .setOpenableLayout(drawerLayout)
            .build();
    NavigationUI.setupWithNavController(toolbar, navController, appBarConfiguration);

    navigationView.setNavigationItemSelectedListener(menuItem -> {
        int id = menuItem.getItemId();
        if (id == R.id.fav) {
            navController.navigate(R.id.favouritesFragment);
        } else if (id == R.id.search) {
            AlertDialog.Builder builder = 
                new AlertDialog.Builder(MainActivity.this, 
          R.style.MyAlertDialogStyle);
            SpannableString title = new SpannableString("Cerca");
            title.setSpan(new ForegroundColorSpan(
           Color.parseColor("#2565AE")), 0, title.length(), 
            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            builder.setTitle(title);
            final EditText input = new EditText(MainActivity.this);
            input.setInputType(InputType.TYPE_CLASS_TEXT);
            builder.setView(input);
            builder.setPositiveButton("OK", (dialog, which) -> {
                Bundle bundle = new Bundle();
                bundle.putString("type", input.getText().toString());
                bundle.putBoolean("nearby", false);
                navController.navigate(R.id.nearbyFragment, bundle);
                Toast.makeText(MainActivity.this, input.getText().toString(),          
            Toast.LENGTH_SHORT).show();
            });
            builder.setNegativeButton("Cancel", (dialog, which) -> dialog.cancel());
            builder.show();
        } else if (id == R.id.setting) {
            navController.navigate(R.id.settingsFragment);
        } else if (id == R.id.home) {
            navController.navigate(R.id.homeFragment);
        } else if (id == R.id.bookmarks) {
            navController.navigate(R.id.bookmarksFragment);
        } else if (id == R.id.map) {
            navController.navigate(R.id.mapFragment);
        }
        new Handler().postDelayed(() -> drawerLayout.closeDrawer(navigationView), 200);
        return false;
    });
}

@Override
public boolean onSupportNavigateUp() {
    NavController navController = Navigation.findNavController(this,                    
     R.id.nav_host_fragment);
    return NavigationUI.navigateUp(navController, appBarConfiguration)
            || super.onSupportNavigateUp();
}

@Override
public void onBackPressed() {
    if (drawerLayout.isDrawerOpen(navigationView)) {
        drawerLayout.closeDrawer(navigationView);
    } else {
        super.onBackPressed();
    }
}

Item Layout项目布局

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/cardview_home"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardElevation="5dp"
card_view:cardUseCompatPadding="true"
android:foreground="?android:attr/selectableItemBackground"
android:background="@color/quantum_white_100"
android:clickable="true"
android:focusable="false">

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clickable="false"
    android:focusable="false"
    android:padding="8dp">
    <ImageView
        android:focusable="false"
        android:clickable="false"
        android:layout_marginTop="8dp"
        android:id="@+id/image"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:paddingBottom="5dp"
        android:paddingTop="5dp"
        tools:ignore="ContentDescription" />
    <TextView
        android:focusable="false"
        android:clickable="false"
        android:paddingBottom="5dp"
        android:paddingTop="5dp"
        android:id="@+id/type"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_marginStart="12dp"
        android:layout_marginTop="8dp"
        android:layout_marginBottom="8dp"
        android:layout_toEndOf="@+id/image"
        android:maxLines="1"
        android:textSize="25sp"
        android:textStyle="bold"
        android:theme="@style/HomeListViewTheme"
        tools:ignore="HardcodedTextRtlHardcoded" />
 </RelativeLayout>

  </androidx.cardview.widget.CardView>

Home fragment layout主页片段布局

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/recyclerview_fav"
    android:layout_width="match_parent"
    android:background="@color/ghostwhite"
    android:layout_height="match_parent"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="parent" />

  </androidx.constraintlayout.widget.ConstraintLayout>

Main Activity Layout主要活动布局

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout

xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer"
android:layout_width="match_parent"
android:layout_height="match_parent">

<LinearLayout

    android:id="@+id/main_container"
    android:orientation="vertical"
    android:layout_height="wrap_content"
    android:layout_width="match_parent">

    <androidx.appcompat.widget.Toolbar

        android:id="@+id/toolbar5"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary"
        android:minHeight="?attr/actionBarSize"
        android:theme="@style/ToolbarTheme"
        app:titleTextAppearance="@style/ToolbarTheme" />

    <LinearLayout

        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintTop_toBottomOf="@+id/toolbar5"
        android:orientation="horizontal">

        <fragment
            android:id="@+id/nav_host_fragment"
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:defaultNavHost="true"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:navGraph="@navigation/nav_graph"
            tools:ignore="FragmentTagUsage" />

    </LinearLayout>

</LinearLayout>

<com.google.android.material.navigation.NavigationView
    app:headerLayout="@layout/nav_header"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:menu="@menu/nav_menu"
    app:itemTextAppearance="@style/MyMenu"
    android:layout_gravity="start"
    android:id="@+id/navigation_view" />

</androidx.drawerlayout.widget.DrawerLayout>

MenuHolder class MenuHolder class

public class MenuHolder extends RecyclerView.ViewHolder implements View.OnClickListener{

private OnItemClickListener listener;

@BindView(R.id.type)
TextView name;
@BindView(R.id.image)
ImageView img;

public MenuHolder(View itemView, OnItemClickListener listener) {
    super(itemView);
    ButterKnife.bind(this, itemView);
    itemView.setOnClickListener(this);
    this.listener = listener;
}

public void displayView(String type, int image) {
    name.setText(type);
    img.setImageResource(image);
}

public void onClick(View view) {
    listener.onClick(view, getAdapterPosition());
}

} }

Interface OnItemClickListener接口 OnItemClickListener

public interface OnItemClickListener {

void onClick(View view, int position);

} }

Make your own OnCLickListener :制作自己的OnCLickListener

public interface RecyclerViewClickListener {
        void recyclerViewListClicked(View v, int position);
    } 

Remember to create instance of it inside your adapter class请记住在您的适配器 class 中创建它的实例

RecyclerViewClickListener itemClickListsner;

Create your custom ViewHolder class:创建您的自定义ViewHolder class:

public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        // your fields here


        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            // get fields from XML by findViewById()

           itemView.setOnClickListener(this);

        }

        @Override
        public void onClick(View view) {
            itemClickListener.recyclerViewListClicked(itemView, this.getLayoutPosition());
        }
    }

And now you can pass your `RecyclerViewClickListener'现在你可以通过你的 `RecyclerViewClickListener'

public HomeAdapter(RecyclerViewClickListener clickListener) {

     this.itemClickListener = clickListener;

}

And inside Actitivy:在 Activity 内部:

HomeAdapter(new RecyclerViewClickListener() {
            @Override
            public void recyclerViewListClicked(View view, int position) {

        });

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

相关问题 活动重启后Recyclerview不更新 - Recyclerview not updating after activity restart 自定义ListView onClick更改图像,重新启动活动后notifyDataSetInvalidated无法正常工作 - Custom ListView onClick change Image, notifyDataSetInvalidated not working after restart activity AlarmManager 仅在应用程序重启后工作 - AlarmManager only works after App restart 为什么重启活动后我的阵列可以重新工作? - Why my array works anew after restart activity? 在RecyclerView中使用onClick()启动新的活动 - Start new Activity with onClick() in RecyclerView RecyclerView onClick 导致相同的活动? - RecyclerView onClick result in Same activity? Android:在另一个活动(由RecyclerView启动)调用finish()后无意中激活了RecyclerView项目的onClick() - Android: RecyclerView item's onClick() unintentionally activated after call to finish() by another activity (which was started by that RecyclerView) Android notifyDataSetChanged仅在刷新活动后才能工作 - Android notifyDataSetChanged works only after refreshing activity ItemDecoration 仅在使用 ListAdapter 时重新启动活动后应用 - ItemDecoration applies only after restart activity when using ListAdapter focusTo / onClick事件后的scrollTo仅在第二次单击后有效 - scrollTo after focus/onClick event works only after second click
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM