2017-11-03 30 views
0

私は、リストからプログラムで作成されたボタンのスクロール可能なリスト(列と言う)を生成するアクティビティをsqliteテーブルの読み込みの結果であり、画面の初期ペイントが遅くなっている(ボタンの数が増えている)ので、私はこれに対する解決策を探しています。プログラマチックに作成された大きなボタンの表示を高速化する

最初はスレッド(実行可能ファイル、ハンドラなど)を使用することを考えましたが、Forの内部に新しいスレッドを作成してリストを反復処理しますが、動作していません(少なくとも私は実行できません私の質問は次のようです:

リストから始めて、スクロール可能なボタンの大きなセットを作成する最も適切な方法は、ユーザーが画面にアクセスするときにそのような遅延がないようにすることです。

ページネーションはオプションになる可能性がありますが、最初に他の可能性について知りたい場合は、最後のリソースとして残しておきます。

ありがとうございます、以下は私のコードです。

public static void createButtons(LinearLayout llContainer, 
            List<TestType> TestTypes, List<Test> Tests, 
            int buttonFontSize) { 

     Context oContext = llContainer.getContext(); 
     String strTheme = TMAppearance.getThemeFromPreferences(oContext); 
     testMe = ((ApplicationConfiguration)oContext.getApplicationContext()); 
     int callerActivity = TestTypes!=null ? 2 : 1; 

     if (TestTypes!=null || Tests!=null) { 
      int lCols = strTheme.equals(testMe.theme_vivid) ? 1 : 2; 

      //int sourceElementIndex = 0; 
      int originListSize = calculateOriginalListSize(callerActivity, TestTypes, Tests); 
      int lRows = (int) Math.ceil((double)originListSize/lCols); 

      List<String> aStartColors = TMUtils_ThemeVivid.generateStartColorArray(lRows, oContext); 
      List<String> aEndColors = TMUtils_ThemeVivid.generateEndColorArray(lRows, oContext); 

      for (i = 0; i < lRows; i++) { 

       LinearLayout outerButtonLayout = generateOuterButtonLayout(oContext); 

       for (j = 0; j < lCols; j++) { 

        final Thread r = new Thread() { 
         public void run() { 
          LinearLayout innerButtonLayout = generateInnerButtonLayout(oContext); 
          outerButtonLayout.addView(innerButtonLayout, j); 

          if (sourceElementIndex<originListSize){ 
           final TMButton oButton = new TMButton(oContext); 

           if (callerActivity==1) { //testMenu 
            setTestMenuButtonSettings(oButton, sourceElementIndex, Tests); 
           } else { 
            if (callerActivity==2) { //testTypeMenu 
             setTestTypeMenuButtonSettings(oButton, sourceElementIndex, TestTypes); 
            } 
           } 

           if (strTheme.equals(testMe.theme_vivid)){ 
            oButton.fontSize = buttonFontSize; 
            oButton.gradientStartColor = aStartColors.get(i); 
            oButton.gradientEndColor = aEndColors.get(i); 
           }else{ 
            if (strTheme.equals(testMe.theme_purple)){ 
             oButton.gradientStartColor = testMe.btnStartColor_purple; 
             oButton.gradientEndColor = testMe.btnEndColor_purple; 
            } 
           } 

           configureButton(oButton, callerActivity); 

           oButton.setOnTouchListener(new OnTouchListener() { 
            @Override 
            public boolean onTouch(View v, MotionEvent event) { 

             Context oContext = v.getContext(); 
             TMButton oButton = (TMButton) v; 

             int callerActivity = Integer.valueOf(v.getTag().toString().split("@")[0]); 
             String sourceId = String.valueOf(v.getTag().toString().split("@")[1]); 

             if(event.getAction() == MotionEvent.ACTION_DOWN) { //pressed 
              setButtonPressed(oButton); 
              TMSound.playButtonSound(oContext); 
             } else if (event.getAction() == MotionEvent.ACTION_UP) { //released 
              setButtonReleased(oButton); 
              startTargetActivity(callerActivity, sourceId, oContext); 
             } 

             return true; 
            } 
           }); 
           TMAppearance.doButtonAnimation(oContext, oButton, i); 
           innerButtonLayout.addView(oButton); 
           sourceElementIndex++; 
          } 
         } 
        }; 
        r.run(); 
       } 
       llContainer.addView(outerButtonLayout); 
      } 
     } 
    } 
+0

onClickイベントが、それはRecycleViewにおけるよりも実装が容易であるということであるあなたがに反対している 'ListView'または' RecycleView'の使用についての何かがありますか?カスタムレイアウトを使用することで、柔軟性を高めることができます。 – Barns

+0

Barns52の返事をいただきありがとうございます。もちろん、私はListViewに反対しているわけではありません。実際にボタンがプログラムによって生成されるため、ListViewを実装する方法を調査しています。 問題なく、動的に生成されたボタンでListViewを使用できると思いませんか? –

+0

私はListView(nostalgia?;-))が好きですが、RecyclerViewはListViewと比べて優れたパフォーマンスを持つように導入されました。スクロールするとき。 – 0X0nosugar

答えて

0

0X0nosugarは正しいです。 A RecycleViewはより良いパフォーマンスを提供しますが、多くの初心者はそれを実装するのが難しく、50ボタンのパフォーマンスでは本当に問題にはなりません。そして、私は一般的にルール '利用可能な最良のソリューションを使用する'を好むが、ListViewを実装する方法を学ぶことはまだ適切だと思う。カスタムアダプタを作成する必要がありますので...

public class MyListDataAdapter extends ArrayAdapter<MyListData> { 

    private static final String TAG = "MyListDataAdapter"; 


    public MyListDataAdapter(Context context, ArrayList<MyListData> data) { 
     super(context, 0, data); 

    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent){ 

     final MyListData data = getItem(position); 

     if(convertView == null){ 
      convertView = LayoutInflater.from(getContext()).inflate(R.layout.edit_list_item, parent, false); 
     } 

     // Add a TextView if you need one 
     final TextView tvName = (TextView) convertView.findViewById(R.id.tvName); 
     Button btnEditTicketHolder = (Button) convertView.findViewById(R.id.btnEdit); 
     btnEditTicketHolder.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       long userId = data.getUserId(); 
       String fName = data.getFirstName(); 

       Intent intent = new Intent(getContext(), EditActivity.class); 
       intent.putExtra("userId", userId); 
       intent.putExtra("fName", fName); 
       getContext().startActivity(intent); 
      } 
     }); 


     String name = data.getFirstName(); 
     tvName.setText(name); 
     return convertView; 
    } 

} 

を今、あなたはデータを保持するために、あなたのMyListDataクラスが必要:

public class MyListData { 

    // Add more as you need 
    private long userId; 
    private String firstName; 

    public MyListData(){ 
    } 


    public void setFirstName(String name){ this.firstName = name; } 
    public void setUserId(long id){ this.userId = id; } 

    public String getFirstName(){ return this.firstName; } 
    public long getUserId(){ return this.userId; } 
} 

カスタムListViewレイアウトは同じようなものを見ることができます:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
       xmlns:app="http://schemas.android.com/apk/res-auto" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" 
    > 

    <LinearLayout 
     android:orientation="vertical" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentLeft="true" 
     android:layout_centerVertical="true" 
     > 

     <TextView 
      android:id="@+id/tvName" 
      android:text="With Whom" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      /> 

    </LinearLayout> 

    <LinearLayout 
     android:orientation="vertical" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentRight="true" 
     android:layout_centerVertical="true" 
     > 

     <Button 
      android:id="@+id/btnEdit" 
      android:layout_width="wrap_content" 
      android:layout_height="40dp" 
      android:paddingRight="10dp" 
      android:paddingLeft="10dp" 
      android:text="Edit" 
      android:backgroundTint="@color/colorAccent" 
      android:focusable="false" 
      /> 

    </LinearLayout> 

</RelativeLayout> 

アクティビティ(例:onCreate()メソッド)ListViewのデータを入力する必要があります。 (私は小さな利点の1つを見つける:これはないListViewは、あなたがそれらを必要とする場合、いくつかのonClickイベントハンドラを設定し維持する活動にもUIスレッド

ArrayList<MyListData> arrayListData = new ArrayList<MyListData>(); 
    MyListDataAdapter adapter = new MyListDataAdapter(this, arrayListData); 

    for (MyListData g : result) { 
     adapter.add(g); 
    } 
    mLstMy.setAdapter(adapter); 

に行われる必要がありますListView

mMyLst = (ListView) findViewById(lstMy); 
mMyLst.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
    @Override 
    public void onItemClick(AdapterView<?> parent, View view, int position, long l) { 
     MyListData data = (MyListData) parent.getItemAtPosition(position); 
     selectedName = data.getName(); 

     Intent intent = new Intent(ShowListDataActivity.this, MainActivity.class); 
     startActivity(intent); 
    } 
}); 

mMyLst.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { 
    @Override 
    public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) { 

     MyListData data = (MyistData) adapterView.getItemAtPosition(i); 
     selectedName = data.getFirstName(); 

     selectedTicketPosition = i; 
     // removeValue is my own method for removing an entry from the 
     // list MyListData and then call adapter.notifyDataSetChanged(); 
     removeValue(i); 

     return true; 
    } 
}); 
+0

ListViewの素晴らしい説明については非常に@ Barns52ありがとうございます。 最後に、私はRecyclerViewを実装することができましたが、結果は同じで、遅延がsqliteクエリにあることがわかりました。 私はそのクエリを最適化できました。その結果、スクリーンレンダリングがはるかに高速になりました。 すべてのListViewチュートリアルであなたの努力のために正しい答えを設定します。 –

関連する問題