【问题标题】:Item Decorator adding extra space, each time it is called, how to handle this issue?Item Decorator 增加额外空间,每次调用,如何处理?
【发布时间】:2017-06-22 11:50:50
【问题描述】:

我遇到了与以下问题中所述几乎相同的问题,希望我正在使用改造。我希望将数据传递给 spaceDecorator 方法,因此每次更改或刷新我的设置时,都会添加额外的空间。

RecyclerView decorator adding extra padding on refresh

我尝试了上面建议的所有解决方案,但没有奏效。请提出解决此问题的方法。

我的代码:

public class MainActivity extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener {

    public static final String top_rated = "http://api.themoviedb.org/3/movie/top_rated?api_key=1401a8cfe672a592a1a72b023d9febd7";

    public static final String popular = "http://api.themoviedb.org/3/movie/popular?api_key=1401a8cfe672a592a1a72b023d9febd7";

    public static final String baseUrl = "http://api.themoviedb.org/3/";

    public static final String apiKEy = "1401a8cfe672a592a1a72b023d9febd7";

    public static final String preUrl = "http://image.tmdb.org/t/p/w342";

    public static List<MovieData> movieDataList;

    private static SpaceDecorator spaceDecorator;

    private RecyclerView recyclerView;
    private RecyclerView.Adapter adapter;
    private RecyclerView.LayoutManager layoutManager;
    private  ProgressDialog mProgressDialog;

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

        recyclerView = (RecyclerView)findViewById(R.id.main_recyclerview);
        recyclerView.setHasFixedSize(true);
        layoutManager = new GridLayoutManager(MainActivity.this,2);
        recyclerView.setLayoutManager(layoutManager);

        //use a layout manager, a grid layout manager with 2 columns in our case

        updateJson();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if(item.getItemId() == R.id.action_settings){
            startActivity(new Intent(this, SettingsActivity.class));
            return true;
        }

        return super.onOptionsItemSelected(item);
    }


    private void updateJson(){
        mProgressDialog = new ProgressDialog(MainActivity.this);
        mProgressDialog.setIndeterminate(true);
        mProgressDialog.setMessage("Loading...");
        mProgressDialog.show();

        Retrofit retrofit = new Retrofit.Builder()
                            .baseUrl(baseUrl)
                            .addConverterFactory(GsonConverterFactory.create())
                            .build();
        final RequestInterface requestInterface = retrofit.create(RequestInterface.class);

        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        String sort_by = sharedPreferences.getString("sort_by","popular");

        Call<JsonMovieResponse> call = requestInterface.getTopRatedMovies(sort_by, apiKEy);
        call.enqueue(new Callback<JsonMovieResponse>() {

            @Override
            public void onResponse(Call<JsonMovieResponse> call, Response<JsonMovieResponse> response) {

                movieDataList = response.body().getResults();
                adapter = new MainRecyclerViewAdapter(MainActivity.this, movieDataList);
                recyclerView.setAdapter(adapter);
                spaceDecorator = new SpaceDecorator(4,adapter.getItemCount());
                recyclerView.addItemDecoration(spaceDecorator);

                if(mProgressDialog.isShowing())
                    mProgressDialog.dismiss();
            }

            @Override
            public void onFailure(Call<JsonMovieResponse> call, Throwable t) {
                Log.e("retrofit error", t.toString());
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        PreferenceManager.getDefaultSharedPreferences(this).
                unregisterOnSharedPreferenceChangeListener(this);
        Log.i("main","destroy");
    }

    @Override
    protected void onResume() {
        super.onResume();
        PreferenceManager.getDefaultSharedPreferences(this).
                registerOnSharedPreferenceChangeListener(this);
        Log.i("activity","main resume");
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) {
        Log.i("main settings", "changed");
        updateJson();
    }
}

【问题讨论】:

  • 您可能有同样的问题,但代码不同。请添加它的所有相关部分。
  • 发布您的相关代码。
  • 我已添加代码

标签: android android-recyclerview retrofit


【解决方案1】:

考虑您的onResponse() 方法,您将spaceDecorator 添加为物品装饰。这种方法是累加的,因此对于每次更新,您都会在项目之间添加空格。相反,您必须先删除旧的spaceDecorator,然后再添加新的。

@Override
public void onResponse(Call<JsonMovieResponse> call, Response<JsonMovieResponse> response) {

    movieDataList = response.body().getResults();
    adapter = new MainRecyclerViewAdapter(MainActivity.this, movieDataList);
    recyclerView.setAdapter(adapter);

    if (spaceDecorator != null)
        recyclerView.removeItemDecoration(spaceDecorator);

    spaceDecorator = new SpaceDecorator(4,adapter.getItemCount());
    recyclerView.addItemDecoration(spaceDecorator);

    if(mProgressDialog.isShowing())
        mProgressDialog.dismiss();
}

【讨论】:

  • 感谢成功,我正在寻找一些 recycleview 方法来检查是否添加了 itemdecorator,但我认为没有这样的方法可用
【解决方案2】:

添加前请尝试移除itemDecoration,如下图:

            movieDataList = response.body().getResults();
            adapter = new MainRecyclerViewAdapter(MainActivity.this, movieDataList);
            recyclerView.setAdapter(adapter);
            if(spaceDecorator != null){
                 recyclerView.removeItemDecoration(spaceDecorator);
            }
            spaceDecorator = new SpaceDecorator(4,adapter.getItemCount());
            recyclerView.addItemDecoration(spaceDecorator);

            if(mProgressDialog.isShowing())
                mProgressDialog.dismiss();

每次调用 addItemDecoration 方法时,都会调用 itemDecoration 类中的 onDraw。在该方法中,如果您使用每个单元格的布局参数来添加空间,那么在第一次它将是正确的。在随后调用单元格的布局参数时,之前添加的空间将在那里。所以先删除空间,然后添加新空间。

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2013-01-13
    • 2019-09-15
    • 2016-05-30
    • 1970-01-01
    • 1970-01-01
    • 2011-01-01
    • 2020-09-30
    • 2012-08-12
    • 1970-01-01
    相关资源
    最近更新 更多