有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java RecyclerView在第一次加载时不显示数据

我已经修复了项目(here)的上一个问题,但是出现了一个新问题。。。 我将把需要的类放在这里,这样任何或多或少懒惰的人都可以从那里读东西


问题

第1步启动应用程序
第2步从导航栏中选择一个项目
第3步-错误不加载数据,不显示任何内容
第4步从导航栏中选择任何其他项目
第5步一切正常

基本上第一次“不起作用”。在第4步之后,在我应用任何更改或重建应用程序之前,一切都正常。


文件

main活动

public class MainActivity extends AppCompatActivity {

    private DrawerLayout drawer;
    private Handler mHandler;

    private static final String TAG_00 = "home";
    private static final String TAG_01 = "gui_yast";
    private static final String TAG_02 = "gui_network";
    private static final String TAG_03 = "gui_users";
    private static final String TAG_04 = "gui_remote";
    private static final String TAG_05 = "gui_disks";
    private static final String TAG_06 = "gui_install";
    private static final String TAG_07 = "gui_custom";
    private static final String TAG_08 = "gui_gvim";
    private static final String TAG_09 = "cli_fs";
    private static final String TAG_10 = "cli_intro";
    private static final String TAG_11 = "cli_vim";
    private static final String TAG_12 = "cli_remote";
    private static final String TAG_13 = "cli_init";
    private static final String TAG_14 = "cli_process";
    private static final String TAG_15 = "cli_users";
    private static final String TAG_16 = "cli_software";
    private static final String TAG_17 = "cli_admin";
    private static final String TAG_18 = "cli_rescue";
    public static String CURR_TAG = TAG_00;

    private NavigationView navigationView;
    public int navItemIndex = 0;
    private String[] fragmentTitles;
    boolean shouldLoadHomeOnBack = true;
    Fragment fragment;

    Utils u = Utils.getInstance();

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

        fragmentTitles = getResources().getStringArray(R.array.nav_fragment_titles);
        mHandler = new Handler();
        navigationView = findViewById(R.id.nav_view);

        drawer = findViewById(R.id.drawer_layout);

        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.addDrawerListener(toggle);
        toggle.syncState();

        setUpNavigationView();

        if (savedInstanceState == null) {
            navItemIndex = 0;
            CURR_TAG = TAG_00;
            loadHomeFragment();
        }

    }

    public void loadHomeFragment() {
        selectNavMenu();
        setToolbarTitle();
        if (getSupportFragmentManager().findFragmentByTag(CURR_TAG) != null) {
            drawer.closeDrawers();
            return;
        }
        Log.d("FragmentTransaction","Step before transaction");

        Runnable pendingRunnable = new Runnable() {
            @Override
            public void run() {
                Fragment fragment = getHomeFragment();
                FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
                Log.d("FragmentTransaction","Transaction began");
                fragmentTransaction.replace(R.id.frame_container, fragment, CURR_TAG);
                fragmentTransaction.commitAllowingStateLoss();
                Log.d("FragmentTransaction","Transaction "+CURR_TAG+" is finished");
            }
        };

        mHandler.post(pendingRunnable);
        drawer = findViewById(R.id.drawer_layout);
        drawer.closeDrawers();
        invalidateOptionsMenu();
    }

    private Fragment getHomeFragment() {
        switch (navItemIndex) {
            case 0:
                u.setItemLoaded(0);
                fragment = new HomeFragment();
                return fragment;
            default:
                u.setItemLoaded(navItemIndex);
                new AsyncListLoad(u.getURL(navItemIndex),this).execute();
                fragment = new ContentFragment();
                return fragment;
        }
    }

    private void setToolbarTitle() {
        getSupportActionBar().setTitle(fragmentTitles[navItemIndex]);
    }

    private void selectNavMenu() {
        navigationView.getMenu().getItem(navItemIndex).setChecked(false);
    }

    private void setUpNavigationView() {
        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                int id = item.getItemId();
                switch (id) {
                    case R.id.nav_home:
                        navItemIndex = 0;
                        CURR_TAG = TAG_00;
                        break;
                    case R.id.gui_yast:
                        navItemIndex = 1;
                        CURR_TAG = TAG_01;
                        break;
                    case R.id.gui_network:
                        navItemIndex = 2;
                        CURR_TAG = TAG_02;
                        break;
                    case R.id.gui_users:
                        navItemIndex = 3;
                        CURR_TAG = TAG_03;
                        break;
                    // There's 18, so I'll skip them
                }
                loadHomeFragment();

                return true;
            }
        });
    }

    @Override
    public void onBackPressed() {
        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawers();
            return;
        }

        // This code loads home fragment when back key is pressed
        // when user is in other fragment than home
        if (shouldLoadHomeOnBack) {
            // checking if user is on other navigation menu
            // rather than home
            if (navItemIndex != 0) {
                navItemIndex = 0;
                CURR_TAG = TAG_00;
                loadHomeFragment();
                return;
            }
        }

        super.onBackPressed();
    }

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

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

Utils

public class Utils {

    private static final Utils ourInstance = new Utils();

    public static Utils getInstance() {
        return ourInstance;
    }

    private Utils() {
    }

    public ArrayList<String> subURL = new ArrayList<>();

    public String getSubURL(int i) {
        return subURL.get(i);
    }

    public void addSubURL(String subURL, int stringIndex) {
        this.subURL.add(stringIndex,subURL);
    }

    public void clearSubList() {
        subURL.clear();
    }

    public int itemLoaded;
    public int subItemLoaded;
    private ArrayList<DataItem> dataSet = new ArrayList<>();
    private ArrayList<Article> articleSet = new ArrayList<>();

    public void setItemLoaded(int itemLoaded) {
        this.itemLoaded = itemLoaded;
    }

    public int getItemLoaded() {
        return itemLoaded;
    }

    public void setDataSet(ArrayList<DataItem> dataSet) {
        this.dataSet = dataSet;
    }

    public ArrayList<DataItem> getDataSet() {
        return dataSet;
    }

    public ArrayList<Article> getArticleSet() {
        return articleSet;
    }

    public void setArticleSet(ArrayList<Article> articleSet) {
        this.articleSet = articleSet;
    }

    public int getSubItemLoaded() {
        return subItemLoaded;
    }

    public void setSubItemLoaded(int subItemLoaded) {
        this.subItemLoaded = subItemLoaded;
    }

    public String getURL(int itemLoaded) {
        switch (itemLoaded) {
            case 1:
                return "http://susehowto.dx.am/gui/yast";
            case 2:
                return "http://susehowto.dx.am/gui/network";
            case 3:
                return "http://susehowto.dx.am/gui/users";
            case 4:
                return "http://susehowto.dx.am/gui/remote";
            case 5:
                return "http://susehowto.dx.am/gui/disks";
            case 6:
                return "http://susehowto.dx.am/gui/install";
            case 7:
                return "http://susehowto.dx.am/gui/custom";
            case 8:
                return "http://susehowto.dx.am/gui/gvim";
            case 9:
                return "http://susehowto.dx.am/cli/fs";
            case 10:
                return "http://susehowto.dx.am/cli/intro";
            case 11:
                return "http://susehowto.dx.am/cli/vim";
            case 12:
                return "http://susehowto.dx.am/cli/remote";
            case 13:
                return "http://susehowto.dx.am/cli/init";
            case 14:
                return "http://susehowto.dx.am/cli/process";
            case 15:
                return "http://susehowto.dx.am/cli/users";
            case 16:
                return "http://susehowto.dx.am/cli/software";
            case 17:
                return "http://susehowto.dx.am/cli/admin";
            case 18:
                return "http://susehowto.dx.am/cli/rescue";
            default:
                return "";
        }
    }
}

AsyncListLoad

public class AsyncListLoad extends AsyncTask<String,Void,ArrayList<DataItem>> {

    private Activity activity;
    private String target_url;
    private ArrayList<DataItem> dataSet;
    private Utils u = Utils.getInstance();
    private ProgressDialog dialog;

    public AsyncListLoad(String url, Activity activity) {
        this.activity = activity;
        dialog = new ProgressDialog(activity);
        this.target_url = url;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        dialog.setIndeterminate(false);
        dialog.setMessage("Ładowanie zawartości");
        dialog.setCancelable(false);
        dialog.show();
    }

    @Override
    protected ArrayList<DataItem> doInBackground(String... strings) {
        dataSet = new ArrayList<>();
        try {
            Document mSectionDocument = Jsoup.connect(target_url).get();
            Elements mElementSectionSize = mSectionDocument.select("div[class=section]");
            int mElementSize = mElementSectionSize.size();
            u.clearSubList();
            for (int i=0; i < mElementSize; i++) {
                Elements mElementSectionTitle = mSectionDocument.select("span[class=section-name]").select("a").eq(i);
                String mSectionTitle = mElementSectionTitle.text();

                Elements sectionLinks = mSectionDocument.select("span[class=section-name]").select("a").eq(i);
                String sectionLink = sectionLinks.attr("href");
                u.addSubURL(sectionLink,i);

                Elements mElementSectionDesc = mSectionDocument.select("span[class=section-desc]").eq(i);
                String mSectionDesc = mElementSectionDesc.text();
                if(i>9)u.addSubURL(target_url+"/section_"+(i+1),i);
                else u.addSubURL(target_url+"/section_0"+(i+1),i);
                dataSet.add(new DataItem(mSectionTitle,mSectionDesc));
                Log.d("DataItemCreation","Item no. "+i+" added");
                Log.d("DataItemCreation","Link: "+u.getSubURL(i));
                Log.d("DataItemCreation","Item title: "+dataSet.get(i).getTopicTitle());
                Log.d("DataItemCreation","Item description: "+dataSet.get(i).getTopicDesc());
            }
            publishProgress();
        } catch (HttpStatusException h) {
            Toast.makeText(activity,"Network error",Toast.LENGTH_SHORT).show();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return dataSet;
    }

    @Override
    protected void onPostExecute(ArrayList<DataItem> arrayList) {
        arrayList = this.dataSet;
        u.setDataSet(arrayList);
        Log.d("DataSetup","DataSet acquired and loaded.");
        dialog.dismiss();
        RecyclerView recyclerView = activity.findViewById(R.id.content_rv);
        ContentAdapter adapter = (ContentAdapter) recyclerView.getAdapter();
        adapter.notifyDataSetChanged();
    }
}

ContentFragment

public class ContentFragment extends Fragment {

    public ContentAdapter adapter;
    Utils u = Utils.getInstance();
    private static final String TAG = "ContentFragment";
    protected ArrayList<DataItem> dataSet;
    protected RecyclerView.LayoutManager lm;
    protected RecyclerView recyclerView;

    public ContentFragment() {
        //empty public constructor
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initData();
        adapter = new ContentAdapter(dataSet, getActivity());
        lm = new LinearLayoutManager(getActivity());
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable final ViewGroup container, Bundle savedInstanceState) {
        final View v = inflater.inflate(R.layout.content_fragment,container,false);
        v.setTag(TAG);
        recyclerView = v.findViewById(R.id.content_rv);
        setCustomAdapter(recyclerView, lm, adapter);
        final SwipeRefreshLayout rLayout = v.findViewById(R.id.content_swipe);

        rLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                rLayout.setRefreshing(true);
                Toast.makeText(getActivity(),"Refreshed!",Toast.LENGTH_SHORT).show();
                rLayout.setRefreshing(false);
            }
        });
        return v;
    }

    private void initData() {
        dataSet = u.getDataSet();
    }

    public void setCustomAdapter(RecyclerView recyclerView, RecyclerView.LayoutManager layoutManager, ContentAdapter adapter) {
        recyclerView.removeAllViews();
        Log.d("Fragment","RecyclerView added");
        recyclerView.setLayoutManager(layoutManager);
        Log.d("Fragment","LayoutManager is set");
        recyclerView.setAdapter(adapter);
        Log.d("Fragment","Adapter is set");
        adapter.notifyDataSetChanged();
    }
}

ContentAdapter

public class ContentAdapter extends RecyclerView.Adapter<ContentAdapter.ContentViewHolder> {

    private ArrayList<DataItem> dataSet;
    Utils u = Utils.getInstance();
    private Context context;

    public ContentAdapter(ArrayList<DataItem> itemSet, Context context) {
        this.context = context;
        this.dataSet = itemSet;
    }

    @Override
    public long getItemId(int position) {
        return super.getItemId(position);
    }

    @NonNull
    @Override
    public ContentAdapter.ContentViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.data_item,parent,false);
        final ContentViewHolder vHolder = new ContentViewHolder(v);
        vHolder.itemLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d("SubItemClick","Item "+vHolder.getAdapterPosition()+" is clicked!");
                u.setSubItemLoaded(vHolder.getAdapterPosition());
                Intent run = new Intent(context,DynamicActivity.class);
                Bundle fragData = new Bundle();
                fragData.clear();
                fragData.putString("link",u.getSubURL(vHolder.getAdapterPosition()));
                fragData.putInt("ClickedID",vHolder.getAdapterPosition());
                run.putExtras(fragData);
                context.startActivity(run);
            }
        });
        return vHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull ContentViewHolder holder, int position) {
        holder.topicTitle.setText(dataSet.get(position).getTopicTitle());
        holder.topicDesc.setText(dataSet.get(position).getTopicDesc());
        Log.d("ViewHolderSetup","ViewHolder is bind");
    }

    @Override
    public int getItemCount() {
        return dataSet.size();
    }

    public static class ContentViewHolder extends RecyclerView.ViewHolder {

        public CardView itemLayout;
        public TextView topicTitle;
        public TextView topicDesc;
        public ContentViewHolder(View itemView) {
            super(itemView);
            itemLayout = itemView.findViewById(R.id.dataitem_container);
            topicTitle = itemView.findViewById(R.id.topic_title);
            topicDesc = itemView.findViewById(R.id.topic_desc);
        }
    }
}


这里发布的任何数据都将是公开的。提前感谢您的帮助!

共 (1) 个答案

  1. # 1 楼答案

    @ADM提供的解决方案(问题下的注释):数据加载后,需要提供回调,这样应用程序就能够填充已经加载的内容

    本质上,我已经创建了一个名为OnDataLoadListener的接口,并将onDataLoadListenervoid(注意区分大小写,这对于创建这样的接口非常重要)。然后,当加载数据时,我在ContentAdapter内调用这个void来填充数据