2016-04-04 6 views
1

私はナビゲーションドロワーとイメージの設定について学ぶために簡単なアプリケーションを作成しようとしています。私はAndroid Studioが私のために作成したテンプレートにこのアプリを基づいています。Android UIのラグ設定イメージ

ドロアブルを取得することは長いプロセスになる可能性があるので、私はそのためにAsynctaskを作成しました。それにもかかわらず、私のUIはまだまだ遅れており、メインスレッドでの作業が多すぎるためにフレームがスキップされているというメッセージが表示されます。私は次の行がこれらの問題を引き起こしていることを考え出し:

pic.setImageDrawable(drawable); //(in onPostExecute) 

私は、バックグラウンドですべての処理を行なったし、この行がちょうど描画可能に設定する必要があります。これはなぜそんなに遅れているのですか?

寸法を設定すると違いが生じる場合があります。今、私は両方の次元をmatch_parentに設定し、イメージはビューの中央に配置されています。私はそれに明確なサイズを与えたくありません。

public class MainActivity extends AppCompatActivity 
    implements NavigationView.OnNavigationItemSelectedListener { 

private ImageView pic; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
    setSupportActionBar(toolbar); 

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); 
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
      this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); 
    drawer.setDrawerListener(toggle); 
    toggle.syncState(); 

    pic = (ImageView) findViewById(R.id.pic); 

    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view); 
    navigationView.setNavigationItemSelectedListener(this); 

    //set first item to be selected and set its image 
    navigationView.getMenu().getItem(0).setChecked(true); 
    new ImageSetter().execute(); 
} 

@Override 
public void onBackPressed() { 
    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); 
    try { 
     if (drawer.isDrawerOpen(GravityCompat.START)) { 
      drawer.closeDrawer(GravityCompat.START); 
     } else { 
      super.onBackPressed(); 
     } 
    } catch (NullPointerException e) { 
     Log.e("back pressed", e.getStackTrace().toString()); 
    } 
} 

@Override 
public boolean onNavigationItemSelected(MenuItem item) { 
    // Handle navigation view item clicks here. 
    int id = item.getItemId(); 
    new ImageSetter(id).execute(); 

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); 
    drawer.closeDrawer(GravityCompat.START); 
    return true; 
} 

/** 
* class for getting the image drawable in the background and then setting it 
*/ 
private class ImageSetter extends AsyncTask<Integer, Void, Drawable> { 

    int id = //image1; 

    public ImageSetter() { 
    } 

    public ImageSetter(int id) { 
     this.id = id; 
    } 

    /** 
    * Get drawable in background 
    * Precondition: id has already been set 
    * @param params 
    * @return drawable of the picture to set 
    */ 
    @Override 
    protected Drawable doInBackground(Integer... params) { 
     int pic = R.drawable.b1; 

     switch (id) { 
      //set pic 
     } 

     return getResources().getDrawable(pic); 
    } 

    // Once complete, see if ImageView is still around and set drawable 
    @Override 
    protected void onPostExecute(Drawable drawable) { 
     if (pic != null) { 
      pic.setImageDrawable(drawable); 
     } 
    } 
} 

}

+0

http://developer.android.com/training/displaying-bitmaps/load-bitmap.html – tachyonflux

+0

イメージ処理を行う必要がない限り、別のスレッドを使用する必要はありません。最初。フレームをスキップした場合、最も可能性が高いのはdrawableです。 –

+0

@MarkKleen私は彼が、URLから画像を取得するためのAsyncTaskを作ったことを意味していると思いますが、これは間違いなく良い方法です。あなたが言ったように、レイアウト内の画像のみを設定するための別のスレッドはかなり必要ありません。 – privatestaticint

答えて

2

コードは、私には正常に見えます。 setImageDrawable()を使用してもあまり遅れてはならず、UIスレッドで実行する必要があります。あなたは別のスレッドにタスクをオフロードしました。これは良いことです。

フェッチしているソースイメージのサイズはどれくらいですか? Androidは大きな画像を扱う際に悪い知られています...

ソースイメージが大きすぎる場合は、Android開発者サイトのLoading Large Bitmaps Efficientlyをご覧ください。これはあなたにビットマップを扱うためのヒントを与えるでしょう。

関連する問題