OnTouchListener / OnClickListener不是一个片段的布局里面工作 [英] OnTouchListener/OnClickListener not working inside a Fragment's layout

查看:201
本文介绍了OnTouchListener / OnClickListener不是一个片段的布局里面工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请记住我在Android的初学者,所以它可能是某个地方我忽略了一些东西。另外我有一个以上的问题,在这里,因为我的做法对整个项目可能是错误的。

Please keep in mind I'm a beginner in Android, so it is possible that somewhere I overlooked something. Also I have more then one question here, because my approach to the whole project might be wrong.

我有了通过DrawerLayout实现侧面菜单的应用程序。 主屏幕是一个片段,并与抽屉我创建一个有一个列表侧面菜单。之后,这是我在点击侧边菜单中更改片段:

I have an application that has side menu implemented via DrawerLayout. The "main screen" is a Fragment and with Drawer I create the side menu with a list in it. After that this is how I change the fragments upon clicking on the side menu:

private void displayView(int position) {
    // update the main content by replacing fragments

    Fragment fragment = null;
    switch (position) {
        case 0:
            fragment = new HomeFragment();
            break;
        case 1:
            fragment = new FavoritesFragment();
            break;
        case 2:
            fragment = new LastVisitedFragment();
            break;
        case 3:
            fragment = new SettingsFragment();
            break;
        default:
            break;
    }

    if (fragment != null) {
        FragmentManager fragmentManager = getFragmentManager();
        fragmentManager.beginTransaction().replace(R.id.frame_container, fragment).commit();

        // update selected item and title, then close the drawer
        mDrawerList.setItemChecked(position, true);
        mDrawerList.setSelection(position);
        setTitle(navMenuTitles[position]);
        mDrawerLayout.closeDrawer(mDrawerList);
    } else {
        Log.e("MainActivity", "Error in creating fragment");
    }
}

上面的code在我的主要活动是落实。其次,这是我HomeFragment的外观:
(起始片段是我的主页上这样说)

The code above is implemented in my main activity. Next this is how my HomeFragment looks: (The home fragment is my home page so to say)

public class HomeFragment extends Fragment {

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        Log.i("HomeFragment", "OK");
        View rootView = inflater.inflate(R.layout.fragment_home, container, false);
        rootView.setOnClickListener(new View.OnClickListener() {

            @
            Override
            public void onClick(View v) {
                Log.i("HomeFragment", "OK0");
                switch (v.getId()) {
                    case R.id.rec_prod1:
                        Log.i("HomeFragment", "OK1");
                        Intent intent1 = new Intent(getActivity(), SingleItemActivity.class);
                        startActivity(intent1);
                        break;
                    case R.id.rec_prod2:
                        Log.i("HomeFragment", "OK2");
                        Intent intent2 = new Intent(getActivity(), SingleItemActivity.class);
                        startActivity(intent2);
                        break;
                    case R.id.rec_prod3:
                        Log.i("HomeFragment", "OK3");
                        Intent intent3 = new Intent(getActivity(), SingleItemActivity.class);
                        startActivity(intent3);
                        break;

                }
            }
        });


        return rootView;
    }

}

我与onTouchListener尝试它,但也不能工作,唯一不同的是,与onTouch它进入到onTouch方法,赌什么发生后。另外某处在这个网站我有红色的设置滚动视图点击= TRUE,所有孩子的假,以便为它工作,但没有这样做。
此外fragment_home.xml是与母公司是一个滚动型的自定义布局(它有三个coloumns和5行的列表,但每个元素都是不同的,他们都有一个ImageView的和不同数量的textviews,我没有使用一个ListView或GridList因为每一行有一个标题,每行中的元素有不同的布局)我只重视它的概述,因为真正的XML code是超过800线长。

I have tried it with onTouchListener to but didn't work either, the single difference was that with onTouch it entered in to the onTouch method, bet nothing happened after. Also somewhere on this site I have red to set the scrollview clickable=true and all childs to false in order for it to work, but that didn't do either. Also fragment_home.xml is a custom layout with the Parent being a ScrollView (It's a list with three coloumns and 5 rows but each element is different, they all have an Imageview and different number of textviews, I didn't use a ListView or GridList since each row has a title, and the elements in each row have different layouts) I attach only an overview of it since the real xml code is over 800 lines long.

<ScrollView>
<LinearLayout>
   <!--This part repeats 5 times creating each row -->  
   <TextView>   
   <LinearLayout>
     <!-- This part repeats 3 times for each element of a column -->
     <RelativeLayout>
        <ImageView>
            <!-- This part changes acodringly to the number of textviews, I can have 1 to 3 TextViews here-->
            <LinearLayout>
              <TextView>
              <TexytView>
            </LinearLayout>
    </RelativeLayout>
  </LinearLayout>           
</LinearLayout>
</ScrollView> 

所以,我有两个主要问题。
1.为什么没有点击/感人的工作。
2.是项目结构(结构)确定这个样子?整个想法是,当点击发生的一些元素带我去一个产品查看屏幕,而其他产品的元素列表(即填满所有这一切将来自服务器的数据,这就是为什么我在onclick开始了新的活动方法)。

So I have two main questions. 1. Why doesn't the clicking/touching work. 2. Is the project structure(architecture) ok like this? The whole idea is that when a click happens some elements take me to a product view screen, while others to a list of product elements (the data that fills all this will come from a server, that's why I started a new Activity in the onClick method).

推荐答案

您所设置OnClickListener整个片段,而不是你要查询的switch语句的实际看法。当然,具体的code部分从来没有达到!
这种方法应该工作(并正式由谷歌支持用户)href=\"http://stackoverflow.com/a/14571018/2964379\">好评:

You're setting the OnClickListener for the whole fragment, not the actual views you are querying in the switch-statement. Of course the specific code parts are never reached! This approach should work (and is officially supported by Google and well received by users on Stack Overflow):

public class HomeFragment extends Fragment implements View.OnClickListener {

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    Log.i("HomeFragment", "OK");
    View rootView = inflater.inflate(R.layout.fragment_home, container, false);
    rootView.findViewById(R.id.rec_prod1).setOnClickListener(this);
    rootView.findViewById(R.id.rec_prod2).setOnClickListener(this);
    rootView.findViewById(R.id.rec_prod3).setOnClickListener(this);
    return rootView;
}

@Override
public void onClick(View v) {
    Log.i("HomeFragment", "OK0");
    switch (v.getId()) {
    case R.id.rec_prod1:
        Log.i("HomeFragment", "OK1");
        Intent intent1 = new Intent(getActivity(), SingleItemActivity.class);
        startActivity(intent1);
        break;
    case R.id.rec_prod2:
        Log.i("HomeFragment", "OK2");
        Intent intent2 = new Intent(getActivity(), SingleItemActivity.class);
        startActivity(intent2);
        break;
    case R.id.rec_prod3:
        Log.i("HomeFragment", "OK3");
        Intent intent3 = new Intent(getActivity(), SingleItemActivity.class);
        startActivity(intent3);
        break;
    }
}
}

如需进一步阅读:

通过XML设置的onClick也会工作,但遗憾的是,只有在活动,而不是片段:该方法是在片段的父活动调用(请参阅How处理使用XML片段内的onClick)按钮点击。

Setting the onClick via XML would also work, but sadly, only in activities, not in fragments: The method is invoked on the fragment's parent activity (see How to handle button clicks using the xml onClick within Fragments).

不过,上述方法有一个缺点:的onClick是公共的,因此可以从外部调用。例如,父活动可以称之为

Still, the above approach has a disadvantage: onClick is public and thus could be called from outside. For example, the parent activity could call

((View.OnClickListener) homeFragment).onClick(
    homeFragment.getView().findViewById(R.id.rec_prod1));

这将火rec_prod1 onClick事件。 IMO,可读性和便利这种做法带来的远远超过这一点。当然,也有自己的优点和缺点的其他方法。最重要的是,以prevent这个公共访问,您可以创建一个匿名类为每个侦听器(参见尼克的回答和的它的缺点),或使用code以下,而不是:

This would fire an onClick event for rec_prod1. IMO, the readability and convenience this approach brings outweighs this. Of course, there are other approaches with their own advantages and disadvantages. Most importantly, to prevent this public access, you can create an anonymous class for each listener (see Nick's answer and its disadvantages) or use the code below instead:

public class HomeFragment extends Fragment {

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    Log.i("HomeFragment", "OK");
    View rootView = inflater.inflate(R.layout.fragment_home, container, false);
    View.OnClickListener onClick = new RecProdClickListener();
    rootView.findViewById(R.id.rec_prod1).setOnClickListener(onClick);
    rootView.findViewById(R.id.rec_prod2).setOnClickListener(onClick);
    rootView.findViewById(R.id.rec_prod3).setOnClickListener(onClick);
    return rootView;
}

private class RecProdClickListener implements View.OnClickListener {
    @Override
    public void onClick(View v) {
        Log.i("HomeFragment", "OK0");
        switch (v.getId()) {
        case R.id.rec_prod1:
            Log.i("HomeFragment", "OK1");
            Intent intent1 = new Intent(getActivity(), SingleItemActivity.class);
            startActivity(intent1);
            break;
        case R.id.rec_prod2:
            Log.i("HomeFragment", "OK2");
            Intent intent2 = new Intent(getActivity(), SingleItemActivity.class);
            startActivity(intent2);
            break;
        case R.id.rec_prod3:
            Log.i("HomeFragment", "OK3");
            Intent intent3 = new Intent(getActivity(), SingleItemActivity.class);
            startActivity(intent3);
            break;
        }
    }
}
}

所有的旁边那几个匿名点击听众将导致更多的内存使用和稍微长一点的时间intialization,而重用点击监听器与开关语句会使业绩的更糟糕的可以忽略不计,由于圈复杂度

但是,你甚至可以混合使用不同的方法。最终,这取决于你的口味。在讨论什么是最好下将属于programmers.stackexchange什么情况下,肯定是在Android开发清洁code一个有趣的话题。

But you can even mix the different approaches. Ultimately, it's up to your taste. Discussing what's best under what circumstances would belong to programmers.stackexchange and surely is an interesting topic for clean code in Android development.

这篇关于OnTouchListener / OnClickListener不是一个片段的布局里面工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆