【问题标题】:How do I use a foreach loop to clean up this verbose patch of code?如何使用 foreach 循环来清理这个冗长的代码补丁?
【发布时间】:2012-10-29 08:25:05
【问题描述】:

Java/Android 初学者在这里。我在我的应用程序中使用了自定义字体,并且为每段文本创建 setTypeface() 语句会影响我的代码质量。

当前代码:

Typeface Helvetica = Typeface.createFromAsset(getAssets(), "fonts/Helvetica.otf");

final TextView Nike = (TextView)findViewById(R.id.Nike);
final TextView Puma = (TextView)findViewById(R.id.Puma);
final TextView Adidas = (TextView)findViewById(R.id.Adidas);
final TextView Reebok = (TextView)findViewById(R.id.Reebok);
final TextView Umbro = (TextView)findViewById(R.id.Umbro);

Nike.setTypeface(Helvetica);
Puma.setTypeface(Helvetica);
Adidas.setTypeface(Helvetica);
Reebok.setTypeface(Helvetica);
Umbro.setTypeface(Helvetica);

如何缩短此代码?我正在考虑一个带有数组的 foreach 循环,但我似乎无法弄清楚。这样的事情是否可能:

String[] HelveticaTextArray = {"Nike", "Puma", "Adidas", "Reebok", "Umbro"};

for ( String[] HelveticaTextArray : item ) {
    final TextView HelveticaText = (TextView).findViewById(R.id.item);
    HelveticaText.setTypeface(Helvetica);
};

【问题讨论】:

  • 如果只有5个Views也没关系,不要把事情弄复杂了。
  • 在我的示例中为 5,在我的实际应用中约为 12-15。真的很长很丑。

标签: java android foreach


【解决方案1】:

由于您为每个TextView 做同样的事情,我倾向于创建一个方便的方法来满足您的需要,传入R.id.xxx 和字体。例如,

private void initializeViews() {
    Typeface Helvetica = Typeface.createFromAsset(getAssets(), "fonts/Helvetica.otf");

    final TextView Nike = initializeTextView(R.id.Nike, Helvetica);
    final TextView Puma = initializeTextView(R.id.Puma, Helvetica);
    final TextView Adidas = initializeTextView(R.id.Adidas, Helvetica);
    final TextView Reebok = initializeTextView(R.id.Reebok, Helvetica);
    final TextView Umbro = initializeTextView(R.id.Umbro, Helvetica);

}

private TextView initializeTextView(int textViewId, Typeface typeface) {
    TextView textView = (TextView)findViewById(textViewId);
    if (textView != null)
        textView.setTypeface(typeface);
    else
        Log.e(TAG, "some error message");
    return textView;
}

【讨论】:

    【解决方案2】:

    您可以存储 int ID 而不是字符串。

    //String[] HelveticaTextArray = {"Nike", "Puma", "Adidas", "Reebok", "Umbro"};
    int[] HelveticaTextArray = {R.id.Nike, R.id.Puma, R.id.Adidas, R.id.Reebok, R.id.Umbro}
    
    
    for ( int[] HelveticaTextArray : item ) {
        final TextView HelveticaText = (TextView)findViewById(item);
        HelveticaText.setTypeface(Helvetica);
    };
    

    除非您永远不会对这些 TextView 做任何事情,否则我建议您不要这样做。 findViewByID() 是一个相对昂贵的调用,如果您稍后需要使用 TextView 引用,您应该保留它们而不是多次调用 findViewById()

    最好用 HelveticaTextView 之类的子类继承 TextView 并在构造函数中设置字体,然后使用它代替 TextView,这样您就不必在 Activity 中弄乱字体了。

    类似这样的:

    public class HelveticaTextView extends TextView{
        public HelveticaTextView(Context c){
            Typeface Helvetica = Typeface.createFromAsset(c.getAssets(), "fonts/Helvetica.otf");
            super(c);
            this.setTypeface(Helvetica);
        }
        public HelveticaTextView(Context c, AttributeSet attrs){
        Typeface Helvetica = Typeface.createFromAsset(c.getAssets(), "fonts/Helvetica.otf");
            super(c, attrs);
            this.setTypeface(Helvetica);
        }
        public HelveticaTextView(Context context, AttributeSet attrs, int defStyle) {
        Typeface Helvetica = Typeface.createFromAsset(c.getAssets(), "fonts/Helvetica.otf");
            super(c, attrs, defStyle);
            this.setTypeface(Helvetica);
        }
    }
    

    然后在您的 xml 布局中更改

    <TextView .../>
    

    <com.your.package.name.HelveticaTextView .../>
    

    【讨论】:

    • 很好的回复!我同意您对findViewById 的建议,并将牢记这一点。这是我的第一个应用程序,所以子类有点超出我的范围。我理解它的要点,但我无法理解您的子类中的 3 种方法。他们彼此有什么不同?这个子类会在它自己的 .java 文件中包含必要的导入等吗?
    • 是的,它会放在自己的 .java 文件中,是的,它需要一些导入,如果你在 eclipse 中 ctrl+shift+o 会为你修复它们。这些是TextView 拥有的 3 个构造函数。通过将 setTypeface() 放入构造函数中,我们 TextView 在创建后就已经设置了 helvetica。
    • 您好,我尝试了您的子类,但出现错误。你能帮助我吗?由于错误不得不改变一些事情。我将super(c, ..) 放在Typeface Helvetica ... 上方。在最后一个构造函数中,我将Context context 更改为Context c。然后使用我的&lt;com.my.package.HelveticaTextView /&gt;,它说无法实例化该类。它声称Typeface.createfromasset() is not supported。很遗憾,因为我真的很喜欢这个子类的想法。
    • 这很奇怪 - 尽管我遇到了这些错误,但它确实有效。我在模拟器中测试过,字体是Helvetica。但是这些错误让我很担心,也让 XML 的图形布局变得毫无用处。
    【解决方案3】:
    int[] HelveticaArray = {R.id.Nike, R.id.Puma, R.id.Reebok, R.id.Umbro};
    
    for (int item : HelveticaArray) {
        ((TextView).findViewById(item)).setTypeFace(Helvetica);
    }
    

    【讨论】:

    • 不错,简单干净。谢谢。你能解释一下为什么你的for 语句是(int item : HelveticaArray) 而不是(int[] HelveticaArray : item) 吗?它们是等价的吗?
    • 我只看到它按照我的方式完成。甚至 Java 教程都在示例中使用了我的方法。
    【解决方案4】:

    大概是这样的:

    TextView[] textViews = { (TextView) findViewById(R.id.Nike), (TextView) findViewById(R.id.Puma) };
    
    for (TextView view : textViews) {
       view.setTypeface(Helvetica);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-18
      • 1970-01-01
      相关资源
      最近更新 更多