Android TableLayout子TextView点击处理:获取元素信息并跳转Fragment
问题描述
我需要实现点击Android TableLayout内的特定TextView时,打开新Fragment并传递被点击元素的标识信息。当前给id为row16的TableRow设置了点击事件,但只能获取到该行的ID,无法获取被点击的子TextView的ID或tag,尝试使用tag也未解决问题,求可行方案。
对应的布局文件代码:
<TableLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="15dp" android:id="@+id/tableLayoutWeek" > <!--riga dei giorni--> <TableRow android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/blueBlack" android:padding="20dp" > <TextView android:layout_width="50dp" android:layout_height="wrap_content" android:layout_margin="5dp" android:text="lun" android:textAllCaps="true" android:textColor="#FFFFFF" /> <TextView android:layout_width="60dp" android:layout_height="wrap_content" android:layout_margin="5dp" android:text="mar" android:textAllCaps="true" android:textColor="#FFFFFF" /> <TextView android:layout_width="60dp" android:layout_height="wrap_content" android:layout_margin="5dp" android:text="mer" android:textAllCaps="true" android:textColor="#FFFFFF" /> <TextView android:layout_width="60dp" android:layout_height="wrap_content" android:layout_margin="5dp" android:text="gio" android:textAllCaps="true" android:textColor="#FFFFFF" /> <TextView android:layout_width="60dp" android:layout_height="wrap_content" android:layout_margin="5dp" android:text="ven" android:textAllCaps="true" android:textColor="#FFFFFF" /> </TableRow> <!--riga delle 16--> <TableRow android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/yellowRow" android:padding="20dp" android:id="@+id/row16" > <TextView android:id="@+id/lun16" android:layout_width="60dp" android:layout_height="60dp" android:text="16:00" android:textStyle="bold" android:textAllCaps="true" android:textColor="@color/black" android:layout_margin="5dp" /> <TextView android:id="@+id/mar16" android:textStyle="bold" android:layout_width="60dp" android:layout_height="60dp" android:text="16:00" android:textAllCaps="true" android:textColor="@color/black" android:layout_margin="5dp"/> <TextView android:tag="mer16" android:textStyle="bold" android:layout_width="60dp" android:layout_height="60dp" android:text="16:00" android:textAllCaps="true" android:textColor="@color/black" android:layout_margin="5dp"/> <TextView android:tag="gio16" android:textStyle="bold" android:layout_width="60dp" android:layout_height="60dp" android:text="16:00" android:textAllCaps="true" android:textColor="@color/black" android:layout_margin="5dp"/> <TextView android:tag="ven16" android:textStyle="bold" android:layout_width="60dp" android:layout_height="60dp" android:text="16:00" android:textAllCaps="true" android:textColor="@color/black" android:layout_margin="5dp"/> </TableRow> <!--riga delle 17--> <TableRow android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/yellowRow" android:padding="20dp" > <TextView android:textStyle="bold" android:layout_width="60dp" android:layout_height="60dp" android:text="17:00" android:textAllCaps="true" android:textColor="@color/black" android:layout_margin="5dp"/> <TextView android:textStyle="bold" android:layout_width="60dp" android:layout_height="60dp" android:text="17:00" android:textAllCaps="true" android:textColor="@color/black" android:layout_margin="5dp"/> <TextView android:textStyle="bold" android:layout_width="60dp" android:layout_height="60dp" android:text="17:00" android:textAllCaps="true" android:textColor="@color/black" android:layout_margin="5dp"/> <TextView android:textStyle="bold" android:layout_width="60dp" android:layout_height="60dp" android:text="17:00" android:textAllCaps="true" android:textColor="@color/black" android:layout_margin="5dp"/> <TextView android:textStyle="bold" android:layout_width="60dp" android:layout_height="60dp" android:text="17:00" android:textAllCaps="true" android:textColor="@color/black" android:layout_margin="5dp"/> </TableRow> <!--riga delle 18--> <TableRow android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/yellowRow" android:padding="20dp" > <TextView android:textStyle="bold" android:layout_width="60dp" android:layout_height="60dp" android:text="18:00" android:textAllCaps="true" android:textColor="@color/black" android:layout_margin="5dp"/> <TextView android:textStyle="bold" android:layout_width="60dp" android:layout_height="60dp" android:text="18:00" android:textAllCaps="true" android:textColor="@color/black" android:layout_margin="5dp"/> <TextView android:textStyle="bold" android:layout_width="60dp" android:layout_height="60dp" android:text="18:00" android:textAllCaps="true" android:textColor="@color/black" android:layout_margin="5dp"/> <TextView android:textStyle="bold" android:layout_width="60dp" android:layout_height="60dp" android:text="18:00" android:textAllCaps="true" android:textColor="@color/black" android:layout_margin="5dp"/> <TextView android:textStyle="bold" android:layout_width="60dp" android:layout_height="60dp" android:text="18:00" android:textAllCaps="true" android:textColor="@color/black" android:layout_margin="5dp"/> </TableRow> <!--riga delle 19--> <TableRow android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/yellowRow" android:padding="20dp" > <TextView android:textStyle="bold" android:layout_width="60dp" android:layout_height="60dp" android:text="19:00" android:textAllCaps="true" android:textColor="@color/black" android:layout_margin="5dp"/> <TextView android:textStyle="bold" android:layout_width="60dp" android:layout_height="60dp" android:text="19:00" android:textAllCaps="true" android:textColor="@color/black" android:layout_margin="5dp"/> <TextView android:textStyle="bold" android:layout_width="60dp" android:layout_height="60dp" android:text="19:00" android:textAllCaps="true" android:textColor="@color/black" android:layout_margin="5dp"/> <TextView android:textStyle="bold" android:layout_width="60dp" android:layout_height="60dp" android:text="19:00" android:textAllCaps="true" android:textColor="@color/black" android:layout_margin="5dp"/> <TextView android:textStyle="bold" android:layout_width="60dp" android:layout_height="60dp" android:text="19:00" android:textAllCaps="true" android:textColor="@color/black" android:layout_margin="5dp" /> </TableRow> </TableLayout>
尝试过的代码:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { binding = FragmentWeekBinding.inflate(inflater, container, false); View root = binding.getRoot(); binding.row16.setClickable(true); binding.row16.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { int id = view.getId(); Toast.makeText(getContext(), "pos:" + id, Toast.LENGTH_SHORT).show(); } }); return root; }
可行解决方案
方案1:直接为每个目标TextView设置点击事件
这是最直观的方式,给需要响应点击的TextView单独绑定监听器,直接获取其ID或Tag信息。
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { binding = FragmentWeekBinding.inflate(inflater, container, false); View root = binding.getRoot(); // 给有ID的TextView设置点击事件 setTextViewClickListener(binding.lun16); setTextViewClickListener(binding.mar16); // 给只有Tag的TextView设置点击事件 TextView mer16 = binding.row16.findViewWithTag("mer16"); setTextViewClickListener(mer16); TextView gio16 = binding.row16.findViewWithTag("gio16"); setTextViewClickListener(gio16); TextView ven16 = binding.row16.findViewWithTag("ven16"); setTextViewClickListener(ven16); return root; } private void setTextViewClickListener(TextView textView) { textView.setOnClickListener(v -> { // 获取标识信息:优先取ID名称,无ID则取Tag String identifier = v.getId() != View.NO_ID ? getResources().getResourceEntryName(v.getId()) : (String) v.getTag(); // 打开新Fragment并传递参数 openTargetFragment(identifier); }); } private void openTargetFragment(String identifier) { TargetFragment fragment = new TargetFragment(); Bundle args = new Bundle(); args.putString("SELECTED_ITEM", identifier); fragment.setArguments(args); getParentFragmentManager() .beginTransaction() .replace(R.id.fragment_container, fragment) .addToBackStack(null) .commit(); }
方案2:通过TableRow的触摸事件定位子TextView
如果不想逐个设置监听器,可以利用TableRow的触摸事件,通过坐标判断点击的是哪个子TextView。
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { binding = FragmentWeekBinding.inflate(inflater, container, false); View root = binding.getRoot(); binding.row16.setOnTouchListener((v, event) -> { if (event.getAction() == MotionEvent.ACTION_UP) { float touchX = event.getX(); float touchY = event.getY(); // 遍历TableRow的子View,找到被点击的TextView for (int i = 0; i < ((ViewGroup) v).getChildCount(); i++) { View child = ((ViewGroup) v).getChildAt(i); if (child instanceof TextView) { Rect hitRect = new Rect(); child.getHitRect(hitRect); if (hitRect.contains((int) touchX, (int) touchY)) { String identifier = child.getId() != View.NO_ID ? getResources().getResourceEntryName(child.getId()) : (String) child.getTag(); openTargetFragment(identifier); return true; } } } } return false; }); return root; } private void openTargetFragment(String identifier) { TargetFragment fragment = new TargetFragment(); Bundle args = new Bundle(); args.putString("SELECTED_ITEM", identifier); fragment.setArguments(args); getParentFragmentManager() .beginTransaction() .replace(R.id.fragment_container, fragment) .addToBackStack(null) .commit(); }
注意事项
- 建议给所有需要识别的TextView统一设置ID,这样可以直接通过ViewBinding获取,避免ID和Tag混合使用的混乱;
R.id.fragment_container需要替换成你布局中用于承载Fragment的容器ID;- 如果使用Kotlin,可以利用扩展函数简化代码逻辑。
内容的提问来源于stack exchange,提问作者cristoball92
相关产品推荐
相关产品推荐

