替换 LinearLayout 权重机制

2024-02-15

背景:

  • 出于性能考虑,Google 建议避免使用嵌套加权线性布局。
  • 使用嵌套加权线性布局的读、写和维护都很糟糕。
  • 仍然没有好的替代方案来放置可用大小的 % 的视图。唯一的解决方案是权重和使用 OpenGL。甚至没有像 WPF/Silverlight 上显示的“viewBox”之类的东西来自动缩放。

这就是为什么我决定创建自己的布局,您可以告诉它的每个子元素与其大小相比,它们的权重(和周围的权重)到底应该是多少。

看来我已经成功了,但由于某种原因,我认为存在一些我无法追踪的错误。

bug 之一是 textView,尽管我为它提供了很多空间,但它还是将文本放在顶部而不是中间。另一方面,imageViews 工作得很好。另一个错误是,如果我在自定义布局中使用布局(例如frameLayout),则不会显示其中的视图(但布局本身会显示)。

请帮我弄清楚为什么会出现这种情况。

如何使用:而不是线性布局的下一个用法(我故意使用很长的 XML,以展示我的解决方案如何缩短时间):

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
  android:layout_height="match_parent" android:orientation="vertical">

  <View android:layout_width="wrap_content" android:layout_height="0px"
    android:layout_weight="1" />

  <LinearLayout android:layout_width="match_parent"
    android:layout_height="0px" android:layout_weight="1"
    android:orientation="horizontal">

    <View android:layout_width="0px" android:layout_height="wrap_content"
      android:layout_weight="1" />

    <TextView android:layout_width="0px" android:layout_weight="1"
      android:layout_height="match_parent" android:text="@string/hello_world"
      android:background="#ffff0000" android:gravity="center"
      android:textSize="20dp" android:textColor="#ff000000" />

    <View android:layout_width="0px" android:layout_height="wrap_content"
      android:layout_weight="1" />

  </LinearLayout>
  <View android:layout_width="wrap_content" android:layout_height="0px"
    android:layout_weight="1" />
</LinearLayout>

我所做的很简单(x 是将视图本身放在权重列表中的位置):

<com.example.weightedlayouttest.WeightedLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res/com.example.weightedlayouttest"
  xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
  android:layout_height="match_parent" tools:context=".MainActivity">

  <TextView android:layout_width="0px" android:layout_height="0px"
    app:horizontalWeights="1,1x,1" app:verticalWeights="1,1x,1"
    android:text="@string/hello_world" android:background="#ffff0000"
    android:gravity="center" android:textSize="20dp" android:textColor="#ff000000" />

</com.example.weightedlayouttest.WeightedLayout>

我的特殊布局的代码是:

public class WeightedLayout extends ViewGroup
  {
  @Override
  protected WeightedLayout.LayoutParams generateDefaultLayoutParams()
    {
    return new WeightedLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
    }

  @Override
  public WeightedLayout.LayoutParams generateLayoutParams(final AttributeSet attrs)
    {
    return new WeightedLayout.LayoutParams(getContext(),attrs);
    }

  @Override
  protected ViewGroup.LayoutParams generateLayoutParams(final android.view.ViewGroup.LayoutParams p)
    {
    return new WeightedLayout.LayoutParams(p.width,p.height);
    }

  @Override
  protected boolean checkLayoutParams(final android.view.ViewGroup.LayoutParams p)
    {
    final boolean isCorrectInstance=p instanceof WeightedLayout.LayoutParams;
    return isCorrectInstance;
    }

  public WeightedLayout(final Context context)
    {
    super(context);
    }

  public WeightedLayout(final Context context,final AttributeSet attrs)
    {
    super(context,attrs);
    }

  public WeightedLayout(final Context context,final AttributeSet attrs,final int defStyle)
    {
    super(context,attrs,defStyle);
    }

  @Override
  protected void onLayout(final boolean changed,final int l,final int t,final int r,final int b)
    {
    for(int i=0;i<this.getChildCount();++i)
      {
      final View v=getChildAt(i);
      final WeightedLayout.LayoutParams layoutParams=(WeightedLayout.LayoutParams)v.getLayoutParams();
      //
      final int availableWidth=r-l;
      final int totalHorizontalWeights=layoutParams.getLeftHorizontalWeight()+layoutParams.getViewHorizontalWeight()+layoutParams.getRightHorizontalWeight();
      final int left=l+layoutParams.getLeftHorizontalWeight()*availableWidth/totalHorizontalWeights;
      final int right=r-layoutParams.getRightHorizontalWeight()*availableWidth/totalHorizontalWeights;
      //
      final int availableHeight=b-t;
      final int totalVerticalWeights=layoutParams.getTopVerticalWeight()+layoutParams.getViewVerticalWeight()+layoutParams.getBottomVerticalWeight();
      final int top=t+layoutParams.getTopVerticalWeight()*availableHeight/totalVerticalWeights;
      final int bottom=b-layoutParams.getBottomVerticalWeight()*availableHeight/totalVerticalWeights;
      //
      v.layout(left+getPaddingLeft(),top+getPaddingTop(),right+getPaddingRight(),bottom+getPaddingBottom());
      }
    }

  // ///////////////
  // LayoutParams //
  // ///////////////
  public static class LayoutParams extends ViewGroup.LayoutParams
    {
    int _leftHorizontalWeight =0,_rightHorizontalWeight=0,_viewHorizontalWeight=0;
    int _topVerticalWeight    =0,_bottomVerticalWeight=0,_viewVerticalWeight=0;

    public LayoutParams(final Context context,final AttributeSet attrs)
      {
      super(context,attrs);
      final TypedArray arr=context.obtainStyledAttributes(attrs,R.styleable.WeightedLayout_LayoutParams);
        {
        final String horizontalWeights=arr.getString(R.styleable.WeightedLayout_LayoutParams_horizontalWeights);
        //
        // handle horizontal weight:
        //
        final String[] words=horizontalWeights.split(",");
        boolean foundViewHorizontalWeight=false;
        int weight;
        for(final String word : words)
          {
          final int viewWeightIndex=word.lastIndexOf('x');
          if(viewWeightIndex>=0)
            {
            if(foundViewHorizontalWeight)
              throw new IllegalArgumentException("found more than one weights for the current view");
            weight=Integer.parseInt(word.substring(0,viewWeightIndex));
            setViewHorizontalWeight(weight);
            foundViewHorizontalWeight=true;
            }
          else
            {
            weight=Integer.parseInt(word);
            if(weight<0)
              throw new IllegalArgumentException("found negative weight:"+weight);
            if(foundViewHorizontalWeight)
              _rightHorizontalWeight+=weight;
            else _leftHorizontalWeight+=weight;
            }
          }
        if(!foundViewHorizontalWeight)
          throw new IllegalArgumentException("couldn't find any weight for the current view. mark it with 'x' next to the weight value");
        }
        //
        // handle vertical weight:
        //
        {
        final String verticalWeights=arr.getString(R.styleable.WeightedLayout_LayoutParams_verticalWeights);
        final String[] words=verticalWeights.split(",");
        boolean foundViewVerticalWeight=false;
        int weight;
        for(final String word : words)
          {
          final int viewWeightIndex=word.lastIndexOf('x');
          if(viewWeightIndex>=0)
            {
            if(foundViewVerticalWeight)
              throw new IllegalArgumentException("found more than one weights for the current view");
            weight=Integer.parseInt(word.substring(0,viewWeightIndex));
            setViewVerticalWeight(weight);
            foundViewVerticalWeight=true;
            }
          else
            {
            weight=Integer.parseInt(word);
            if(weight<0)
              throw new IllegalArgumentException("found negative weight:"+weight);
            if(foundViewVerticalWeight)
              _bottomVerticalWeight+=weight;
            else _topVerticalWeight+=weight;
            }
          }
        if(!foundViewVerticalWeight)
          throw new IllegalArgumentException("couldn't find any weight for the current view. mark it with 'x' next to the weight value");
        }
      //
      arr.recycle();
      }

    public LayoutParams(final int width,final int height)
      {
      super(width,height);
      }

    public LayoutParams(final ViewGroup.LayoutParams source)
      {
      super(source);
      }

    public int getLeftHorizontalWeight()
      {
      return _leftHorizontalWeight;
      }

    public void setLeftHorizontalWeight(final int leftHorizontalWeight)
      {
      _leftHorizontalWeight=leftHorizontalWeight;
      }

    public int getRightHorizontalWeight()
      {
      return _rightHorizontalWeight;
      }

    public void setRightHorizontalWeight(final int rightHorizontalWeight)
      {
      if(rightHorizontalWeight<0)
        throw new IllegalArgumentException("negative weight :"+rightHorizontalWeight);
      _rightHorizontalWeight=rightHorizontalWeight;
      }

    public int getViewHorizontalWeight()
      {
      return _viewHorizontalWeight;
      }

    public void setViewHorizontalWeight(final int viewHorizontalWeight)
      {
      if(viewHorizontalWeight<0)
        throw new IllegalArgumentException("negative weight:"+viewHorizontalWeight);
      _viewHorizontalWeight=viewHorizontalWeight;
      }

    public int getTopVerticalWeight()
      {
      return _topVerticalWeight;
      }

    public void setTopVerticalWeight(final int topVerticalWeight)
      {
      if(topVerticalWeight<0)
        throw new IllegalArgumentException("negative weight :"+topVerticalWeight);
      _topVerticalWeight=topVerticalWeight;
      }

    public int getBottomVerticalWeight()
      {
      return _bottomVerticalWeight;
      }

    public void setBottomVerticalWeight(final int bottomVerticalWeight)
      {
      if(bottomVerticalWeight<0)
        throw new IllegalArgumentException("negative weight :"+bottomVerticalWeight);
      _bottomVerticalWeight=bottomVerticalWeight;
      }

    public int getViewVerticalWeight()
      {
      return _viewVerticalWeight;
      }

    public void setViewVerticalWeight(final int viewVerticalWeight)
      {
      if(viewVerticalWeight<0)
        throw new IllegalArgumentException("negative weight :"+viewVerticalWeight);
      _viewVerticalWeight=viewVerticalWeight;
      }
    }
  }

我接受了您的挑战并尝试创建您描述的布局以回应我的评论。你是对的。实现起来出人意料地困难。除此之外,我确实喜欢拍摄家蝇。所以我加入并想出了这个解决方案。

  1. 扩展现有的布局类,而不是从头开始创建自己的布局类。我一开始就使用了RelativeLayout,但是所有这些都可以使用相同的方法。这使您能够在您不想操作的子视图上使用该布局的默认行为。

  2. 我向布局添加了四个属性,称为顶部、左侧、宽度和高度。我的目的是通过允许“10%”、“100px”、“100dp”等值来模仿 HTML。此时唯一接受的值是表示父级百分比的整数。 “20”= 布局的 20%。

  3. 为了获得更好的性能,我允许 super.onLayout() 执行所有迭代,并且仅在最后一次传递时使用自定义属性来操作视图。由于这些视图将独立于兄弟姐妹进行定位和缩放,因此我们可以在其他一切都解决后移动它们。

这是 atts.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="HtmlStyleLayout">
        <attr name="top" format="integer"/>
        <attr name="left" format="integer"/>
        <attr name="height" format="integer"/>
        <attr name="width" format="integer"/>

    </declare-styleable>
</resources>

这是我的布局类。

package com.example.helpso;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;


public class HtmlStyleLayout extends RelativeLayout{

    private int pass =0;
    @Override
      protected HtmlStyleLayout.LayoutParams generateDefaultLayoutParams()
        {
        return new HtmlStyleLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
        }

      @Override
      public HtmlStyleLayout.LayoutParams generateLayoutParams(final AttributeSet attrs)
        {
        return new HtmlStyleLayout.LayoutParams(getContext(),attrs);
        }

      @Override
      protected RelativeLayout.LayoutParams generateLayoutParams(final android.view.ViewGroup.LayoutParams p)
        {
        return new HtmlStyleLayout.LayoutParams(p.width,p.height);
        }

      @Override
      protected boolean checkLayoutParams(final android.view.ViewGroup.LayoutParams p)
        {
        final boolean isCorrectInstance=p instanceof HtmlStyleLayout.LayoutParams;
        return isCorrectInstance;
        }

    public HtmlStyleLayout(Context context, AttributeSet attrs) {
        super(context, attrs);

    }

    public void setScaleType(View v){
        try{
            ((ImageView) v).setScaleType (ImageView.ScaleType.FIT_XY);
        }catch (Exception e){
            // The view is not an ImageView 
        }
    }


    @Override
      protected void onLayout(final boolean changed,final int l,final int t,final int r,final int b)
        {
        super.onLayout(changed, l, t, r, b);           //Let the parent layout do it's thing


        pass++;                                        // After the last pass of
        final int childCount = this.getChildCount();   // the parent layout
        if(true){                        // we do our thing


            for(int i=0;i<childCount;++i)
              {
              final View v=getChildAt(i);
              final HtmlStyleLayout.LayoutParams params = (HtmlStyleLayout.LayoutParams)v.getLayoutParams();

              int newTop = v.getTop();                 // set the default value
              int newLeft = v.getLeft();               // of these to the value
              int newBottom = v.getBottom();           // set by super.onLayout() 
              int newRight= v.getRight();             
              boolean viewChanged = false;

              if(params.getTop() >= 0){
                  newTop = ( (int) ((b-t) * (params.getTop() * .01))  );
                  viewChanged = true;
              }

              if(params.getLeft() >= 0){
                  newLeft = ( (int) ((r-l) * (params.getLeft() * .01))  );
                  viewChanged = true;
              }

              if(params.getHeight() > 0){
                  newBottom = ( (int) ((int) newTop + ((b-t) * (params.getHeight() * .01)))  );
                  setScaleType(v);                        // set the scale type to fitxy
                  viewChanged = true;
              }else{
                  newBottom = (newTop + (v.getBottom() - v.getTop()));
                  Log.i("heightElse","v.getBottom()=" +
                          Integer.toString(v.getBottom())
                          + " v.getTop=" +
                          Integer.toString(v.getTop()));
              }

              if(params.getWidth() > 0){
                  newRight = ( (int) ((int) newLeft + ((r-l) * (params.getWidth() * .01)))  );
                  setScaleType(v);
                  viewChanged = true;
              }else{
                  newRight = (newLeft + (v.getRight() - v.getLeft()));
              }

                // only call layout() if we changed something
                if(viewChanged)
                    Log.i("SizeLocation",
                            Integer.toString(i) + ": "
                            + Integer.toString(newLeft) + ", "
                            + Integer.toString(newTop) + ", "
                            + Integer.toString(newRight) + ", "
                            + Integer.toString(newBottom));
                v.layout(newLeft, newTop, newRight, newBottom);
              }





            pass = 0;                                 // reset the parent pass counter
        }
        }


     public  class LayoutParams extends RelativeLayout.LayoutParams
        {

        private int top, left, width, height;
        public LayoutParams(final Context context, final AttributeSet atts) {
            super(context, atts);
            TypedArray a = context.obtainStyledAttributes(atts, R.styleable.HtmlStyleLayout);
            top =  a.getInt(R.styleable.HtmlStyleLayout_top , -1);
            left = a.getInt(R.styleable.HtmlStyleLayout_left, -1);
            width = a.getInt(R.styleable.HtmlStyleLayout_width, -1);
            height = a.getInt(R.styleable.HtmlStyleLayout_height, -1);
            a.recycle();


        }
        public LayoutParams(int w, int h) {
            super(w,h);
            Log.d("lp","2");
        }
        public LayoutParams(ViewGroup.LayoutParams source) {
            super(source);
            Log.d("lp","3");
        }
        public LayoutParams(ViewGroup.MarginLayoutParams source) {
            super(source);
            Log.d("lp","4");
        }
        public int getTop(){
            return top;
        }
        public int getLeft(){
            return left;
        }
        public int getWidth(){
            return width;
        }
        public int getHeight(){
            return height;
        }
        }
}

这是一个活动 xml 示例

<com.example.helpso.HtmlStyleLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:html="http://schemas.android.com/apk/res/com.example.helpso"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:scaleType="fitXY"
        android:src="@drawable/bg" />

    <ImageView
        android:id="@+id/imageView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/overlay"
        html:height="10"
        html:left="13"
        html:top="18"
        html:width="23" />

</com.example.helpso.HtmlStyleLayout>

这是我用于测试的图像。

如果您没有为特定属性设置值,则将使用默认值。因此,如果您设置宽度而不是高度,则图像将按宽度缩放,并按高度换行内容。

压缩的项目文件夹。 https://docs.google.com/open?id=0B2BD9i1zpmm5QVpVcGN6NTNHQ2s

apk https://docs.google.com/open?id=0B2BD9i1zpmm5LWo4d3JCR0VIRWM

我找到了错误的根源。问题是我使用布局的子计数来指示它将对 onLayout 进行多少次调用。这在旧版本的 Android 中似乎并不适用。我注意到在 2.1 中 onLayout 只被调用一次。所以我改变了

if(pass == childCount){

to

if(true){  

它开始按预期工作。

我仍然认为只有在 super 完成之后才调整布局是有益的。只需找到一种更好的方法来知道那是什么时候。

EDIT

我没有意识到您的意图是以像素为单位的精度将图像拼凑在一起。我通过使用双浮点精度变量而不是整数来实现您正在寻找的精度。但是,在允许图像缩放的同时,您将无法实现此目的。放大图像时,会在现有像素之间以一定间隔添加像素。新像素的颜色是周围像素的加权平均值。当您独立缩放图像时,它们不会共享任何信息。结果是你总是会在接缝处出现一些伪影。添加四舍五入的结果,因为您不能有部分像素,并且您将始终具有 +/-1 像素容差。

要验证这一点,您可以在高级照片编辑软件中尝试执行相同的任务。我使用 PhotoShop。我使用与我的 apk 中相同的图像,将它们放在单独的文件中。我将它们垂直缩放了 168%,水平缩放了 127%。然后我将它们放在一个文件中并尝试对齐它们。结果与我的 apk 中看到的完全一样。

为了演示布局的准确性,我向我的 apk 添加了第二个活动。在此活动中,我没有缩放背景图像。其他一切都完全相同。结果是无缝的。

我还添加了一个用于显示/隐藏覆盖图像的按钮和一个用于在活动之间切换的按钮。

我更新了我的谷歌驱动器上的 apk 和压缩项目文件夹。您可以通过上面的链接获取它们。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

替换 LinearLayout 权重机制 的相关文章

随机推荐

  • Spark Streaming kafka 偏移量管理

    我一直在做 Spark Streaming 工作 通过 kafka 消费和生成数据 我使用的是directDstream 所以我必须自己管理偏移量 我们采用redis来写入和读取偏移量 现在有一个问题 当我启动我的客户端时 我的客户端需要从
  • 一个通用的Windows应用程序如何拥有多个独立的窗口(如微软的应用程序“照片”)?

    我确实知道如何使用打开其他窗口TryShowAsStandaloneAsync 然而 如果原来的窗口是关闭的 TryShowAsStandaloneAsync失败 为什么 我不知道如何 复活 它 https stackoverflow co
  • libgdx 绘制汉字

    我喜欢在我的应用程序中打印中文文本 1 当我尝试这个时 屏幕将是空的 控制台没有错误 创建方法 FreeTypeFontGenerator gen new FreeTypeFontGenerator Gdx files internal f
  • Golang编写的UDP客户端无法接收来自服务器的消息

    我写了一个Java客户端 它向广播地址发送消息 我还编写了一个Java服务器 它接受所有发送的消息并将消息发送回客户端 现在我想尝试在 Go 中做同样的事情 只是为了获得一些经验 服务器工作正常 正在接收消息并对 Java 客户端做出响应
  • 删除数组中的所有值,同时保持键不变

    我真的必须这样做才能重置阵列吗 foreach array as i gt value unset array i EDIT 这个更有意义 因为前一个相当于 array array foreach array as i gt value a
  • ARC 并释放方法中创建的对象

    我偶然发现了一个在其他地方找不到答案的问题 当我调用一个返回指向稍后使用的对象的指针并最终设置为 nil 的方法时 它仍然分配在内存中 根据 Instruments 我正在使用 XCode 4 6 3 和 iOS 6 1 ARC 已打开 这
  • OpenCv中如何将Mat的一行复制到另一个Mat的列?

    我有两个垫子 A size 1 640 B size 640 480 我想将 A 复制到 B 的第一列 所以我使用A copyTo B col 0 但是这失败了 怎么做 你走在正确的轨道上 Mat col是要使用的匹配工具 但要注意 简单地
  • appjs - 编译成单个可执行文件?

    我花了整晚的时间尝试不同的工具来通过 html5 构建跨平台桌面应用程序 到目前为止 appjs 似乎很完美 我只玩过基于 Windows 可执行文件的演示项目 但我想知道是否有任何指南或教程介绍如何将项目转换为跨平台可执行文件 单个文件
  • 将小端文件转换为大端文件

    如何将小端二进制文件转换为大端二进制文件 我有一个用 C 编写的二进制文件 我正在使用 Java 中的 DataInputStream 读取这个文件 该文件以大端格式读取 我还查看了 ByteBuffer 类 但不知道如何使用它来获得我想要
  • 带有 Eclipse 和 WTP 插件的 Maven webapp 在 Tomcat 中以奇怪的方式部署文件

    我将 Eclipse J2EE 3 5 与 Maven 和 tomcat 结合使用 为了使用 WTP 部署我的 Maven Web 应用程序 我添加了动态 Web 模块方面并更改了项目的 org eclipse wst common com
  • 具有均匀大小内核的图像卷积

    我想执行简单的 2D 图像卷积 但我的内核大小均匀 我应该为我的内核中心选择哪些指数 我尝试在谷歌上搜索答案并查看现有代码 人们通常将其内核居中 这样在新的 0 之前就会多一个样本 因此 如果我们有一个 4x4 内核 则居中索引应该是 2
  • Android 自动翻译工具 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 你知道有没有free自动本地化工具目前已退出市场 这将是从我的 android 项目翻译我的 XML
  • 如何使用 laravel 在 DOMPDF 中显示印地语字体?

    这是larval中的pdfblade文件 它给 在pdf文件中标记 section css
  • Django 查询超过 5 小时的对象的日期时间

    我正在尝试为 5 小时以上的小部件编写 Django 查询 但我有点迷失了 小部件模型有一个DateTimeField其中填充了小部件的创建时间 If Widget是模型的名称 它有一个名为的 DateTimeField 属性created
  • 如何区分 UIButton 回调操作的触发事件

    在为 UIButton 定义回调时 我列出了同一操作的多个事件 在目标中我希望能够区分触发回调的事件 button addTarget self action selector callback forControlEvents UICon
  • Android:从 SD 卡加载位图时出现“java-lang-outofmemoryerror-bitmap-size-exceeds-vm-budget-android”?

    在我的应用程序中 我必须使用 500x500 像素的小图像显示大约 10000 x 5000 的图像 即通过平铺图像 为了将所有图像平铺为一张 我首先从 SD 卡收集所有位图 以便在画布上绘制 但是当我使用外部存储加载图像时BitmapFa
  • Jquery:TableSorter-特定格式的日期不起作用

    我在用表格分类器 http tablesorter com docs 对表格进行排序的插件 第四列是日期字段 格式为 gt 2013 年 1 月 30 日 gt 2013 年 2 月 1 日 当我尝试对格式进行排序时 它给出了错误的排序 我
  • 在C#中执行Quser windows命令;将结果返回到字符串

    我试图通过 C 执行 Quser windows 命令来返回谁登录到服务器的详细信息 但无法让它工作 我尝试过使用一些指南 但我还没有看到任何适合这种情况的指南 此时命令返回以下内容 Microsoft Windows 版本 6 1 760
  • 42、42.0、“42.0”、“42”之间有什么区别吗

    在使用 Smart Match 测试我的 Perl 代码的过程中 我遇到了这个问题 42 42 0 42 0 42 之间有什么区别吗 var1 42 var2 42 0 a var1 var2 我正进入 状态 a为 0 意思是 var1 a
  • 替换 LinearLayout 权重机制

    背景 出于性能考虑 Google 建议避免使用嵌套加权线性布局 使用嵌套加权线性布局的读 写和维护都很糟糕 仍然没有好的替代方案来放置可用大小的 的视图 唯一的解决方案是权重和使用 OpenGL 甚至没有像 WPF Silverlight