I've fixed my last problem with the project (here), but a new one appeared...
I'll put needed classes here, so any more or less lazy person can just read stuff from there.
Problem
Step 1. Launch an app
Step 2. Select an item from navigation bar
Step 3 - bug. Data doesn't load, nothing appears.
Step 4. Select any other item from navbar
Step 5. Everything works correctly.
Basically the first time "doesn't work". After step 4, everything is normal until I apply any change or rebuild an app.
Files
MainActivity
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);
}
}
}
Any published data here will be public anyway. Thanks in advance for any help!