2016-10-09 27 views
4

Androidグライドを使用してリモート画像を読み込んでいますが、最初の画面の画像は表示されませんが、スクロールして再度スクロールすると奇妙な問題が発生しました。私も、このような質問をGoogleで検索してduplicateを見つけ、そして、このような手順を試した後、それはまだ動作しません。また、あなたがコードをチェックする必要があり、ここではそれはしている enter image description hereAndroidのグライド画像が最初の画面に表示されない

normally.hereを示すなると、スクリーンショットであります
public class SiteAdapter extends ArrayAdapter<Site> { 
private int resourceId; 
private List<Site> sites = null; 
private Context context; 
private SiteHolder siteHolder; 
/** 
* @param context the current activity context, we can get it using the super ArrayAdapter constructor 
* @param resource the site_layout.xml file 
* @param objects the collection to store all the sites 
*/ 
public SiteAdapter(Context context, int resource, List<Site> objects) { 
    super(context, resource, objects); 
    this.context = context; 
    this.resourceId = resource; 
    this.sites = objects; 
} 

@Override 
public Site getItem(int position) { 
    return sites.get(position); 
} 

@Override 
public int getCount() { 
    return sites.size(); 
} 

//get the viewpage which inflate by site_layout.xml file 
@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    Site site = getItem(position); 
    View view = convertView; 
    siteHolder = new SiteHolder(); 
    if (view == null) { 
     LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     view = vi.inflate(resourceId, null); 
    } 
    //this place we need to get the whole widget in site_layout.xml file 
    siteHolder.image = (ImageView) view.findViewById(R.id.thumbnail); 
    siteHolder.address = (TextView)view.findViewById(R.id.address); 
    siteHolder.mallName = (TextView) view.findViewById(R.id.name); 
    siteHolder.distance = (TextView) view.findViewById(R.id.distance); 
    siteHolder.address.setText(site.getAddress()); 
    //set name of the view 
    siteHolder.mallName.setText(site.getName()); 
    //set price of the view 
    //set distance of the view 
    siteHolder.distance.setText("<" + site.getDistance() + "m"); 
    //set image 
    ImageTask task = new ImageTask(); 
    task.execute("http://xxxx/springmvc/getFirst/" + site.getName()); 
    return view; 
} 

//检测adapater中加载网络资源是否可行?结论:不可行 
public String getImgUrl(String str){ 
    String data = ""; 
    try { 
     URL u = new URL(str); 
     HttpURLConnection conn = (HttpURLConnection) u.openConnection(); 
     InputStream is = conn.getInputStream(); 
     BufferedReader br = new BufferedReader(new InputStreamReader(is)); 
     String content = ""; 
     StringBuffer sb = new StringBuffer(); 
     while((content = br.readLine()) != null){ 
      sb.append(content); 
     } 
     data = sb.toString(); 
     br.close(); 
     is.close(); 
    } catch (MalformedURLException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    return data; 
} 
class ImageTask extends AsyncTask<String, Void, String>{ 

    @Override 
    protected String doInBackground(String... str) { 
     String data = ""; 
     data = getImgUrl(str[0]); 
     return data; 
    } 

    @Override 
    protected void onPostExecute(String s) { 
     Glide.with(context) 
      .load(s) 
      .fitCenter() 
      .into(siteHolder.image); 
    } 
} 

class SiteHolder{ 
    ImageView image; 
    TextView mallName; 
    TextView address; 
    TextView distance; 
    } 
} 

このような場面に出会った人がいれば、事前におねがいします。

+1

なぜ画像をダウンロードして直接表示するのですか? 'simpletarget'を使ってイメージをグライドでダウンロードして表示することができます。これは、リストイメージの非同期更新を助けるかもしれません。最後に 'notifydatasetchanged'を呼び出すと、イメージがポスト実行メソッドに設定されます。 –

+0

@MohammedAtif前にあなたのメソッドを試しましたが、まだエラーが発生していますが、' simpletarget'は単にimageviewコールバックです.'notifydatasetchenged'メソッド前にこの質問を投稿し、そのような方法を使用しようとすると失敗しました。多分それはグライド・キャッシュの問題です。初めてグライド・イメージ・データをキャッシュにダウンロードし、再スクロールした後、そのようなキャッシュ・データをグライドして表示します。もしそうなら、私にもっと提案してもらえますか? – Crabime

+0

それは間違いなくnotifydatasetchanged問題です。あなたは適切な時にそれを呼び出す必要があります。あなたはグライドリスナーを追加することができますし、リソース準備メソッドの中でnotifydatasetchangedを呼び出すことができます –

答えて

1

https://github.com/bumptech/glide/issues/1508に対応しながら、私はロードしないあなたのイメージの潜在的な根本原因を発見:getViewにあなたはsiteHolderを上書きするので、どちらImageTask仕上げ、それは常にタスクがために開始されたことを代わりに元の行の最後のバインドされた行を更新します。このようなダブルディスパッチのケースでGlide関連のコードを改善する方法のヒントについては、GitHubの問題を参照してください。素早く汚れた修正:

public class SiteAdapter extends ArrayAdapter<Site> { 
    //private SiteHolder siteHolder; // remove this field 

public View getView(int position, View convertView, ViewGroup parent) { 
    SiteHolder siteHolder = new SiteHolder(); 
    ... 
    ImageTask task = new ImageTask(siteHolder); 
    ... 
} 

static class ImageTask extends AsyncTask<String, Void, String> { 
    private SiteHolder siteHolder; // TODO initialize in constructor 
    // rest stays the same, but notice the `static` modifier above! 
} 
+0

完璧! @TWiStErRobありがとう、私は慎重にGHのあなたの答えを読んで、あなたの分析は本当にあまりにも鋭いです、ちょうどステップでステップを実行し、最終的に本当の苦痛の点を発見した。 – Crabime

2

https://github.com/bumptech/glide/blob/master/README.md#compatibility

ラウンド写真参照してください:(.circleCrop()はV4で利用できるようになりますBitmapTransformationを使用し、TransitionDrawable.thumbnail()または.placeholder().crossFade())とアニメーションGIFとissuesを有することが知られているCircleImageView/CircularImageView/RoundedImageViewを)または.dontAnimate()を入力して問題を解決してください。

簡潔に言えば、丸みを帯びたビューは、入力可能なDrawablesを常にビットマップにラスタライズします。Drawable(GIFまたはcrossFade)内にアニメーションがあれば動作しません。

最初の読み込みでは、イメージを取得している間にプレースホルダが表示され、イメージにクロスフェードされます。後でスクロールアップすると、画像はメモリキャッシュからすぐに読み込まれ、アニメーションは表示されません。

+0

TWiStErRobにお返事いただきありがとうございます。私は互換性に関する記事を見ました。別の3つの外部統合ライブラリを直接追加したアプリをクラッシュさせました。さらに、私はまだ興味があります。まず、Round Pictures?あなたはいくつかのビューを指定しますが、私はただimageviewを使用してアニメーションを使用しないので、dontAnimateも動作しません。 – Crabime

+0

ああ、それは本当です。あなたのプレースホルダ(またはその赤いものが何であれ)は丸みを帯びています。それは私を誤認させますが、最後のものが長方形の画像であることに気付きました。あなたは 'crossFade()'がデフォルトであるので**アニメーションを使用しています。とにかく、GHに関する新しい問題を開くことをお勧めします。私たちはもっと一緒に調査することができます:あなたのViewHolderパターンとAsyncTaskに関する疑いがあります。問題を開くときにすべての詳細を記入してください。 – TWiStErRob

+0

ok、すぐにやります。もっとコードスニペットが必要ですか?しかし、私はこれが孤立した質問だと思います。 – Crabime

関連する問題