草庐IT

android - 在 Horizo​​ntal ScrollView 中滚动会失去焦点元素的焦点,

coder 2023-12-17 原文

滚动前:

滚动期间:

我在滚动过程中的期望:

我对 Horizo​​ntalScrollView 有疑问。当我从此 View 中选择一个元素时,我通过调用将焦点设置到该元素:

else if (v.getParent() == candidatesScrollView.getChildAt(0))
{
    Button candidateButton = (Button) v;
    v.requestFocusFromTouch();
    v.setSelected(true);
            (...)
}

之后,当我滚动列表而不选择其他元素时,我失去了先前选择的元素的焦点。我对这个主题进行了一些研究,但没有适合我的解决方案......如何在不失去所选元素焦点的情况下滚动我的 Horizo​​ntalScrollList?感谢任何帮助。我问这个问题已经 14 天了,但仍然没有找到解决方案。请帮忙。

这是我的 XML 的一部分:

<HorizontalScrollView
        android:id="@+id/CandidatesHorizontalScrollView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_above="@+id/linearLayout2"
        android:clickable="false"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:visibility="gone" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clickable="false"
        android:focusable="false"
        android:focusableInTouchMode="false"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/horizontalscrollview1_button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Button"
            android:textSize="25sp" />

        (...)
        // 11 more buttons
    </LinearLayout>

</HorizontalScrollView>

更新

我当前的解决方案 #1(无法正常工作): 滚动后,然后再次滚动(例如向后滚动),从所选元素开始滚动。

我创建了自定义的 Horizo​​ntalScrollView 类,在其中覆盖了 onTouchEvent() 方法。我不认为这是这样做的最佳方式,因为在那种情况下,每次移动一个像素时我都必须进行计算。例如,如果我将 toast.show() 添加到下面的方法中,它将尝试显示与我移动的像素一样多的 toast(如果我移动 10 个像素,它将尝试显示 10 个 Toast)。无论如何,它对我有用,并且保留了选择和焦点。

请帮我修改这段代码,最终为那个已知问题做出一个好的答案:

@Override
public boolean onTouchEvent(MotionEvent ev)
{
    int i = 0;
    Button button = null;
    for (; i < 11; i++)
    {
        button = (Button)((LinearLayout)getChildAt(0)).getChildAt(i);
        if(button.isSelected())
            break;
    }
    super.onTouchEvent(ev);
    button.setSelected(true);
    button.requestFocusFromTouch();

    return true;
}

为了确保上面的代码能够正常工作,您一次只需要在 Horizo​​ntalScrollView 中选择一个项目,即当您按下不同的按钮时,您需要将前一个设置为 setSelected(false)

我当前的解决方案 #2(无法正常工作):

我尝试实现的解决方案 #2,认为第一个不够优雅,涉及手势检测器的使用。在我的自定义 Horizo​​ntalListView 类中,我添加了以下代码:

构造函数:

public MyHorizontalScrollView(Context context, AttributeSet attrs) {
    super(context, attrs);
    this.context = context;
    gestureDetector = new GestureDetector(context, new MyHorizontalScrollViewGestureDetector());
    this.setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            gestureDetector.onTouchEvent(event);

            return true;
        }
    });
    // TODO Auto-generated constructor stub
}

MyHorizo​​ntalScrollViewGestureDetector 内部类:

public class MyHorizontalScrollViewGestureDetector extends SimpleOnGestureListener
    {

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
        {
            //Here code similar like that one in solution #1
            //But the View is not scrolling, even without that code 
            super.onScroll(e1, e2, distanceX, distanceY);

            return true; 
        }
    }   

但是,列表不会随该解决方案滚动。我可以添加到 onScroll 方法:

ScrollBy((int)positionX, (int)positionY);

这使得列表会滚动,但不是很好的方式,有时它会卡住。 我想知道为什么 super 不调用滚动。方法。

我当前的解决方案 #3(有效,但它是绕行的):

因为解决方案 1 和 2 都不起作用,我决定不再玩焦点了。 我现在所做的是,每当我单击它以及每次更改为不同的按钮时更改 Button Drawable。我使用与用于聚焦按钮 (Holo) 相同的 Drawable。在那种情况下,我不必担心在 Horizo​​ntalScrollView 中滚动。此解决方案是一种临时解决方案,因此我期待收到任何评论、建议和修改。

最佳答案

下面的解决方案是否适用(我从 here 得到的想法):

您可能想尝试创建自己的自定义类来扩展 Horizo​​ntalScrollView 并重写 onScrollChanged() 函数:

public class TestHorizontalScrollView extends HorizontalScrollView {

    public TestHorizontalScrollView(Context context) {
        super(context);
    }


    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        // TODO Auto-generated method stub
        Log.i("Scrolling", "X from ["+oldl+"] to ["+l+"]");
        Button button = null;
        for (; i < 11; i++)
        {
          button = (Button)((LinearLayout)getChildAt(0)).getChildAt(i);
          if(button.isSelected())
            break;
        }
        button.setSelected(true);
        button.requestFocusFromTouch();

        super.onScrollChanged(l, t, oldl, oldt);
    }

}

现在您已经检测到滚动(我们正在谈论 Horizo​​ntalScrollView 之一),您可以再次设置相应按钮的选定状态。你能试试这个解决方案,看看它是否有效。我对这个问题的解决方案很感兴趣,因为这个问题也很有趣。

无论如何,我设法找到了 following article .他们在那里声明:

Imagine a simple application, ApiDemos for example, that shows a list of text items. The user can freely navigate through the list using the trackball and they can also scroll and fling the list using their finger. The issue in this scenario is the selection. If I select an item at the top of the list and then fling the list towards the bottom, what should happen to the selection? Should it remain on the item and scroll off the screen? In this case, what would happen if I then decide to move the selection with the trackball? Or worse, if I press the trackball to act upon the currently selected item, which is not shown on screen anymore. After careful considerations, we decided to remove the selection altogether.

In touch mode, there is no focus and no selection. Any selected item in a list of in a grid becomes unselected as soon as the user enters touch mode. Similarly, any focused widgets become unfocused when the user enters touch mode. The image below illustrates what happens when the user touches a list after selecting an item with the trackball.

无论如何,那里的陈述并没有让我高兴,我进一步发现了这一点:

android:focusable="true"
android:focusableInTouchMode="true"

同时设置android:clickable="true"(你还不如设置LinearLayoutandroid:focusable="true") .

尝试将它们添加到按钮和包含它们的布局中。 尝试一切。

我会尽力支持你。

干杯

关于android - 在 Horizo​​ntal ScrollView 中滚动会失去焦点元素的焦点,,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17140492/

有关android - 在 Horizo​​ntal ScrollView 中滚动会失去焦点元素的焦点,的更多相关文章

  1. ruby - 在哈希的键数组中追加元素 - 2

    查看我的Ruby代码:h=Hash.new([])h[0]=:word1h[1]=h[1]输出是:Hash={0=>:word1,1=>[:word2,:word3],2=>[:word2,:word3]}我希望有Hash={0=>:word1,1=>[:word2],2=>[:word3]}为什么要附加第二个哈希元素(数组)?如何将新数组元素附加到第三个哈希元素? 最佳答案 如果您提供单个值作为Hash.new的参数(例如Hash.new([]),完全相同的对象将用作每个缺失键的默认值。这就是您所拥有的,那是你不想要的。您可以改用

  2. 「Python|Selenium|场景案例」如何定位iframe中的元素? - 2

    本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决

  3. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  4. ruby - Hanami link_to 助手只呈现最后一个元素 - 2

    我是HanamiWorld的新人。我已经写了这段代码:moduleWeb::Views::HomeclassIndexincludeWeb::ViewincludeHanami::Helpers::HtmlHelperdeftitlehtml.headerdoh1'Testsearchengine',id:'title'hrdiv(id:'test')dolink_to('Home',"/",class:'mnu_orizontal')link_to('About',"/",class:'mnu_orizontal')endendendendend我在模板上调用了title方法。htm

  5. ruby - 将n维数组的每个元素乘以Ruby中的数字 - 2

    在Ruby中,是否有一种简单的方法可以将n维数组中的每个元素乘以一个数字?这样:[1,2,3,4,5].multiplied_by2==[2,4,6,8,10]和[[1,2,3],[1,2,3]].multiplied_by2==[[2,4,6],[2,4,6]]?(很明显,我编写了multiplied_by函数以区别于*,它似乎连接了数组的多个副本,不幸的是这不是我需要的)。谢谢! 最佳答案 它的长格式等价物是:[1,2,3,4,5].collect{|n|n*2}其实并没有那么复杂。你总是可以使你的multiply_by方法:c

  6. arrays - 计算数组中的匹配元素 - 2

    给定两个大小相等的数组,如何找到不考虑位置的匹配元素的数量?例如:[0,0,5]和[0,5,5]将返回2的匹配项,因为有一个0和一个5共同;[1,0,0,3]和[0,0,1,4]将返回3的匹配项,因为0有两场,1有一场;[1,2,2,3]和[1,2,3,4]将返回3的匹配项。我尝试了很多想法,但它们都变得相当粗糙和令人费解。我猜想有一些不错的Ruby习惯用法,或者可能是一个正则表达式,可以很好地回答这个解决方案。 最佳答案 您可以使用count完成它:a.count{|e|index=b.index(e)andb.delete_at

  7. ruby - 使用 Nokogiri 和 Ruby 命名元素 "text" - 2

    我在尝试使用Nokogiri构建XML文档时遇到了一个小问题。我想将我的元素之一称为“文本”(请参阅​​下面粘贴代码的最底部)。通常,要创建一个新元素,我会执行类似以下的操作xml.text--但它似乎是.text是Nokogiri已经用来做其他事情的方法。因此,当我写这行时xml.textNokogiri没有创建名为的新元素但只是写了意味着成为元素内容的文本。我怎样才能让Nokogiri实际制作一个名为的元素??builder=Nokogiri::XML::Builder.newdo|xml|xml.TEI("xmlns"=>"http://www.tei-c.org/ns/1.0"

  8. ruby - 在 factory_girl 中有没有办法获取 attributes_for 并为同一个实例元素创建? - 2

    如果我想使用“create”构建策略创建和实例,然后想使用“attributes_for”构建策略进行验证,是否可以这样做?如果我在工厂中使用序列?在Machinistgem中有可能吗? 最佳答案 不太确定我是否完全理解。而且我不是机械师的用户。但听起来您只是想做这样的事情。@attributes=FactoryGirl.attributes_for(:my_object)my_object=MyObject.create(@attributes)my_object.some_property.should==@attributes

  9. ruby - 数组数组中的唯一元素 - 2

    我想通过内部数组中的第一个元素从数组数组中找到唯一元素。例如a=[[1,2],[2,3],[1,5]我想要类似的东西[[1,2],[2,3]] 最佳答案 uniq方法需要一个block:uniq_a=a.uniq(&:first)或者如果您想就地进行:a.uniq!(&:first)例如:>>a=[[1,2],[2,3],[1,5]]=>[[1,2],[2,3],[1,5]]>>a.uniq(&:first)=>[[1,2],[2,3]]>>a=>[[1,2],[2,3],[1,5]]或者>>a=[[1,2],[2,3],[1,5]

  10. arrays - 在一行中选择数组的第一个和最后一个元素 - 2

    我的任务是从数组中选择最高和最低的数字。我想我很清楚我想做什么,但只是努力以正确的格式访问信息以满足通过标准。defhigh_and_low(numbers)array=numbers.split("").map!{|x|x.to_i}array.sort!{|a,b|ba}putsarray[0,-1]end数字可能看起来像"80917234100",要通过,我需要输出"9234"。我正在尝试putsarray.first.last,但一直无法弄明白。 最佳答案 有Array#minmax完全满足您需要的方法:array=[80,

随机推荐