0
I’m creating an app that has a Tablayout with three Tabs that should return specific fragments each. However, when I test the app on mobile none of the tabs are shown, which makes it impossible to do anything. Follow the activity_main layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_weight="1"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/AppTheme.PopupOverlay"
app:title="@string/app_name">
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/title_timeline" />
<android.support.design.widget.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/title_graph" />
<android.support.design.widget.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/title_ll_settings" />
</android.support.design.widget.TabLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="24dip"
tools:context=".MainActivity"
app:layout_behavior="android.support.design.widget.AppBarLayout$ScrollingViewBehavior">
<com.google.android.material.tabs.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top" />
</android.support.v4.view.ViewPager>
Follow the Main Activity:
package com.example.mastiffcollar;
import java.util.Timer;
import java.util.TimerTask;
import com.example.mastiffcollar.contents.ActivityReport;
import com.example.mastiffcollar.contents.ContentObject;
import com.example.mastiffcollar.fragments.GraphFragment;
import com.example.mastiffcollar.fragments.IFragmentListener;
import com.example.mastiffcollar.fragments.LLFragmentAdapter;
import com.example.mastiffcollar.fragments.TimelineFragment;
import com.example.mastiffcollar.service.RetroBandService;
import com.example.mastiffcollar.utils.AppSettings;
import com.example.mastiffcollar.utils.Constants;
import com.example.mastiffcollar.utils.Logs;
import com.example.mastiffcollar.utils.RecycleUtils;
import com.example.mastiffcollar.utils.Utils;
import android.app.ActionBar;
import android.app.Activity;
import android.app.FragmentTransaction;
import android.bluetooth.BluetoothAdapter;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.support.design.widget.TabLayout;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
public class MainActivity extends AppCompatActivity implements ActionBar.TabListener, IFragmentListener {
// Debugging
private static final String TAG = "RetroWatchActivity";
// Context, System
private Context mContext;
private RetroBandService mService;
private Utils mUtils;
private ActivityHandler mActivityHandler;
// Global
// UI stuff
private FragmentManager mFragmentManager;
private LLFragmentAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
private TabLayout mTabLayout;
private ImageView mImageBT = null;
private TextView mTextStatus = null;
// Refresh timer
private Timer mRefreshTimer = null;
/*****************************************************
* Overrided methods
******************************************************/
@Override
public void onCreate(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//----- System, Context
mContext = this;//.getApplicationContext();
mActivityHandler = new ActivityHandler();
AppSettings.initializeAppSettings(mContext);
setContentView(R.layout.activity_main);
// Load static utilities
mUtils = new Utils((MainActivity) mContext);
// Set up the action bar.
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Create the adapter that will return a fragment for each of the primary sections of the app.
mFragmentManager = getSupportFragmentManager();
mSectionsPagerAdapter = new LLFragmentAdapter(mFragmentManager, mContext, this, mActivityHandler);
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.view_pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
mTabLayout = (TabLayout) findViewById(R.id.tabs);
mTabLayout.setupWithViewPager(mViewPager);
// For each of the sections in the app, add a tab to the action bar.
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
// Create a tab with text corresponding to the page title defined by the adapter.
actionBar.addTab(actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
// Setup views
//mImageBT = (ImageView) findViewById(R.id.status_title);
mImageBT.setImageDrawable(getResources().getDrawable(android.R.drawable.presence_invisible));
//mTextStatus = (TextView) findViewById(R.id.status_text);
mTextStatus.setText(getResources().getString(R.string.bt_state_init));
// Do data initialization after service started and binded
doStartService();
}
@Override
public synchronized void onStart() {
super.onStart();
}
@Override
public synchronized void onPause() {
super.onPause();
}
@Override
public void onStop() {
// Stop the timer
if(mRefreshTimer != null) {
mRefreshTimer.cancel();
mRefreshTimer = null;
}
super.onStop();
}
@Override
public void onDestroy() {
super.onDestroy();
finalizeActivity();
}
@Override
public void onLowMemory (){
super.onLowMemory();
// onDestroy is not always called when applications are finished by Android system.
finalizeActivity();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_scan:
// Launch the DeviceListActivity to see devices and do scan
doScan();
return true;
case R.id.action_discoverable:
// Ensure this device is discoverable by others
ensureDiscoverable();
return true;
}
return false;
}
@Override
public void onBackPressed() {
super.onBackPressed(); // TODO: Disable this line to run below code
}
@Override
public void onConfigurationChanged(Configuration newConfig){
// This prevents reload after configuration changes
super.onConfigurationChanged(newConfig);
}
/**
* Implements TabListener
*/
@Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
// When the given tab is selected, switch to the corresponding page in the ViewPager.
mViewPager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
@Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
@Override
public void OnFragmentCallback(int msgType, int arg0, int arg1, String arg2, String arg3, Object arg4) {
switch(msgType) {
case IFragmentListener.CALLBACK_RUN_IN_BACKGROUND:
if(mService != null)
mService.startServiceMonitoring();
break;
default:
break;
}
}
/*****************************************************
* Private methods
******************************************************/
/**
* Service connection
*/
private ServiceConnection mServiceConn = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder binder) {
Log.d(TAG, "Activity - Service connected");
mService = ((RetroBandService.LLServiceBinder) binder).getService();
// Activity couldn't work with mService until connections are made
// So initialize parameters and settings here, not while running onCreate()
initialize();
}
public void onServiceDisconnected(ComponentName className) {
mService = null;
}
};
/**
* Start service if it's not running
*/
private void doStartService() {
Log.d(TAG, "# Activity - doStartService()");
startService(new Intent(this, RetroBandService.class));
bindService(new Intent(this, RetroBandService.class), mServiceConn, Context.BIND_AUTO_CREATE);
}
/**
* Stop the service
*/
private void doStopService() {
Log.d(TAG, "# Activity - doStopService()");
mService.finalizeService();
stopService(new Intent(this, RetroBandService.class));
}
/**
* Initialization / Finalization
*/
private void initialize() {
Logs.d(TAG, "# Activity - initialize()");
mService.setupService(mActivityHandler);
// If BT is not on, request that it be enabled.
// RetroWatchService.setupBT() will then be called during onActivityResult
if(!mService.isBluetoothEnabled()) {
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, Constants.REQUEST_ENABLE_BT);
}
// Load activity reports and display
if(mRefreshTimer != null) {
mRefreshTimer.cancel();
}
// Use below timer if you want scheduled job
//mRefreshTimer = new Timer();
//mRefreshTimer.schedule(new RefreshTimerTask(), 5*1000);
}
private void finalizeActivity() {
Logs.d(TAG, "# Activity - finalizeActivity()");
if(!AppSettings.getBgService()) {
doStopService();
} else {
}
// Clean used resources
RecycleUtils.recursiveRecycle(getWindow().getDecorView());
System.gc();
}
/**
* Launch the DeviceListActivity to see devices and do scan
*/
private void doScan() {
Intent intent = new Intent(this, DeviceListActivity.class);
startActivityForResult(intent, Constants.REQUEST_CONNECT_DEVICE);
}
/**
* Ensure this device is discoverable by others
*/
private void ensureDiscoverable() {
if (mService.getBluetoothScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(intent);
}
}
/*****************************************************
* Public classes
******************************************************/
/**
* Receives result from external activity
*/
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Logs.d(TAG, "onActivityResult " + resultCode);
switch(requestCode) {
case Constants.REQUEST_CONNECT_DEVICE:
// When DeviceListActivity returns with a device to connect
if (resultCode == Activity.RESULT_OK) {
// Get the device MAC address
String address = data.getExtras().getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
// Attempt to connect to the device
if(address != null && mService != null)
mService.connectDevice(address);
}
break;
case Constants.REQUEST_ENABLE_BT:
// When the request to enable Bluetooth returns
if (resultCode == Activity.RESULT_OK) {
// Bluetooth is now enabled, so set up a BT session
mService.setupBT();
} else {
// User did not enable Bluetooth or an error occured
Logs.e(TAG, "BT is not enabled");
Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show();
}
break;
} // End of switch(requestCode)
}
/*****************************************************
* Handler, Callback, Sub-classes
******************************************************/
public class ActivityHandler extends Handler {
@Override
public void handleMessage(Message msg)
{
switch(msg.what) {
// BT state messages
case Constants.MESSAGE_BT_STATE_INITIALIZED:
mTextStatus.setText(getResources().getString(R.string.bt_title) + ": " +
getResources().getString(R.string.bt_state_init));
mImageBT.setImageDrawable(getResources().getDrawable(android.R.drawable.presence_invisible));
break;
case Constants.MESSAGE_BT_STATE_LISTENING:
mTextStatus.setText(getResources().getString(R.string.bt_title) + ": " +
getResources().getString(R.string.bt_state_wait));
mImageBT.setImageDrawable(getResources().getDrawable(android.R.drawable.presence_invisible));
break;
case Constants.MESSAGE_BT_STATE_CONNECTING:
mTextStatus.setText(getResources().getString(R.string.bt_title) + ": " +
getResources().getString(R.string.bt_state_connect));
mImageBT.setImageDrawable(getResources().getDrawable(android.R.drawable.presence_away));
break;
case Constants.MESSAGE_BT_STATE_CONNECTED:
if(mService != null) {
String deviceName = mService.getDeviceName();
if(deviceName != null) {
mTextStatus.setText(getResources().getString(R.string.bt_title) + ": " +
getResources().getString(R.string.bt_state_connected) + " " + deviceName);
mImageBT.setImageDrawable(getResources().getDrawable(android.R.drawable.presence_online));
}
}
break;
case Constants.MESSAGE_BT_STATE_ERROR:
mTextStatus.setText(getResources().getString(R.string.bt_state_error));
mImageBT.setImageDrawable(getResources().getDrawable(android.R.drawable.presence_busy));
break;
// BT Command status
case Constants.MESSAGE_CMD_ERROR_NOT_CONNECTED:
mTextStatus.setText(getResources().getString(R.string.bt_cmd_sending_error));
mImageBT.setImageDrawable(getResources().getDrawable(android.R.drawable.presence_busy));
break;
////////////////////////////////////////////
// Contents changed
////////////////////////////////////////////
case Constants.MESSAGE_READ_ACCEL_REPORT:
ActivityReport ar = (ActivityReport)msg.obj;
if(ar != null) {
TimelineFragment frg = (TimelineFragment) mSectionsPagerAdapter.getItem(LLFragmentAdapter.FRAGMENT_POS_TIMELINE);
frg.showActivityReport(ar);
}
break;
case Constants.MESSAGE_READ_ACCEL_DATA:
ContentObject co = (ContentObject)msg.obj;
if(co != null) {
GraphFragment frg = (GraphFragment) mSectionsPagerAdapter.getItem(LLFragmentAdapter.FRAGMENT_POS_GRAPH);
frg.drawAccelData(co.mAccelData);
}
break;
default:
break;
}
super.handleMessage(msg);
}
} // End of class ActivityHandler
/**
* Auto-refresh Timer
*/
private class RefreshTimerTask extends TimerTask {
public RefreshTimerTask() {}
public void run() {
mActivityHandler.post(new Runnable() {
public void run() {
// TODO:
mRefreshTimer = null;
}
});
}
}
}
And that’s all that appears when the app is operating on the mobile device:
I tested this but it hasn’t worked yet, there is something very specific preventing Viewpager from being presented by Main Activity.
– Ranieri