Issues with Android Soft Keyboard and panAdjust - java

I am trying to achieve similar effect to the one found in Todoits application where you can click on FAB and it shows a floating popup for adding new task.
This is how it looks:
The closest to it I managed to achieve is this:
It is nearly there, but I want the popup to be about 10dp above the keyboard and scroll the recycle viewer to the last item but I can't get it there :/ Currently, the popup is centred.
I have tried before adding the popup to the bottom of the screen and setting android:windowSoftInputMode="adjustResize" but this was moving my bottom navigation above the keyboard too. Setting windowsSoftInputMode to panAdjust was cutting away the toolbar and few items from the list.
Have you got any suggestions about how to achieve similar effect to the one in Todoist? Maybe with a DialogFragment?
Below is my current code (navigation bar implementation is still not completed):
MainActivity:
public class MainActivity extends AppCompatActivity {
private WorkoutsListFragment workoutsListFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar myToolbar = findViewById(R.id.my_toolbar);
setSupportActionBar(myToolbar);
ActionBar actionBar = getSupportActionBar();
this.workoutsListFragment = new WorkoutsListFragment();
getSupportFragmentManager()
.beginTransaction()
.add(R.id.main_layout, workoutsListFragment)
.commit();
}
}
WorkoutListFragment:
public class WorkoutsListFragment extends Fragment
implements View.OnClickListener, WorkoutListViewHolderInterface {
private RecyclerView recyclerView;
private WorkoutListRecycleViewAdapter recycleViewAdapter;
private AddBoxView addBoxView;
private FloatingActionButton actionButton;
private InputMethodManager imm;
private WorkoutViewModel workoutViewModel;
private boolean addBoxStatus;
public WorkoutsListFragment() {}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.addBoxStatus = false;
//Irrelevant code removed (Dagger 2 DI)
this.workoutViewModel =
ViewModelProviders.of(this, workoutViewModelFactory).get(WorkoutViewModel.class);
workoutViewModel.init(7);
workoutViewModel.getWorkout().observe(this, w -> this.updateWorkoutsList(w, false));
this.imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
}
#Override
public View onCreateView(
#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_workouts_list, container, false);
this.recyclerView = view.findViewById(R.id.workoutsList);
// this.recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager recyclerViewLayoutManager = new LinearLayoutManager(getContext());
this.recyclerView.setLayoutManager(recyclerViewLayoutManager);
this.recycleViewAdapter = new WorkoutListRecycleViewAdapter(this);
this.recyclerView.setAdapter(recycleViewAdapter);
this.actionButton = view.findViewById(R.id.floating_action_add_workout);
this.actionButton.setOnClickListener(this);
this.addBoxView = new AddBoxView(Objects.requireNonNull(getContext()));
FrameLayout.LayoutParams addBoxLayoutParams =
new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.WRAP_CONTENT,
Gravity.CENTER);
this.addBoxView.setLayoutParams(addBoxLayoutParams);
this.addBoxView.getButton().setOnClickListener(this);
return view;
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.floating_action_add_workout:
this.addBoxView((FrameLayout) v.getParent(), v);
break;
case R.id.overlay_layout:
removeAddBoxView((FrameLayout) v);
break;
case R.id.button:
this.addNewWorkout(this.addBoxView.getInputText());
break;
}
}
//Irrelevant code removed....
private void addBoxView(FrameLayout viewGroup, View v) {
this.addBoxStatus = true;
viewGroup.setClickable(true);
viewGroup.setOnClickListener(this);
viewGroup.setBackgroundColor(
getResources().getColor(R.color.cardview_shadow_start_color, null));
viewGroup.removeView(v);
viewGroup.addView(this.addBoxView);
this.addBoxView.requestInputFocus();
this.imm.showSoftInput(this.addBoxView.getInput(), InputMethodManager.SHOW_IMPLICIT);
}
private void removeAddBoxView(FrameLayout viewGroup) {
viewGroup.setClickable(false);
this.imm.hideSoftInputFromWindow(this.addBoxView.getInput().getWindowToken(), 0);
viewGroup.removeView(this.addBoxView);
viewGroup.setBackgroundColor(getResources().getColor(R.color.cardview_shadow_end_color, null));
viewGroup.addView(this.actionButton);
this.addBoxStatus = false;
}
}
Fragment_workouts_list layout:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#e1e1e1"
android:padding="0dp"
tools:context=".Activities.MainActivity.Fragments.Workouts.WorkoutsListFragment"
tools:layout_editor_absoluteY="81dp">
<android.support.v7.widget.RecyclerView
android:id="#+id/workoutsList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
android:elevation="0dp"
android:scrollbars="vertical"
app:layout_constraintBottom_toTopOf="#+id/add_box_view"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</android.support.v7.widget.RecyclerView>
<FrameLayout
android:id="#+id/overlay_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="false"
android:outlineProvider="bounds">
<android.support.design.widget.FloatingActionButton
android:id="#+id/floating_action_add_workout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_marginBottom="40dp"
android:layout_marginEnd="40dp"
android:clickable="true"
android:src="#android:color/holo_blue_dark" />
</FrameLayout>
</FrameLayout>
MainActivity Layout
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
android:id="#+id/root_view"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="#+id/my_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="4dp"
android:theme="#style/AppTheme.AppBar" />
<FrameLayout
android:id="#+id/main_layout"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="#+id/navigation"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/my_toolbar">
</FrameLayout>
<android.support.design.widget.BottomNavigationView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/navigation"
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="#color/colorPrimary"
android:foregroundGravity="bottom"
android:visibility="visible"
app:itemTextColor="#color/textColorWhite"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="#menu/my_navigation_items" />
</android.support.constraint.ConstraintLayout>

Related

I implemented card views in XML on Android Studios. How can I have this act as buttons?

I'm new to Android and recently created a dashboard for my app. I followed a tutorial but it only covered the front end. I created a layout called content_main.xml with three Cardviews. Each of these Cardviews contains the code
android:clickable="true"
Beginning the back end of things, I created a java receiver class called DashboardActivity (as seen below). I want to make my Cardviews clickable so that when one is clicked, I am taken to another screen within my app. The other screens in my app I am trying to get to are fragments. Each of these screens has its own java class in my "Fragments" folder. One of them, of which I try calling on in the code that follows is called SettingsViewFragment().
So far, I have tried the following. It does nothing.
public class DashboardActivity extends AppCompatActivity {
CardView cd1, cd2, cd3;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_main);
cd1 = (CardView) findViewById(R.id.dash_settings);
cd2 = (CardView) findViewById(R.id.dash_profile);
cd3 = (CardView) findViewById(R.id.dash_activity);
cd1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Fragment fragment1 = new SettingsViewFragment();
}
});
}
}
UPDATE: FULL CODE
public class DashboardActivity extends AppCompatActivity {
CardView cd1, cd2, cd3;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_main);
cd1 = findViewById(R.id.dash_settings);
cd2 = findViewById(R.id.dash_profile);
cd3 = findViewById(R.id.dash_activity);
cd1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.i("Testing 123 123 123");
}
});
}
}
And my XML: (it continues for 3 cards this way)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.example.newproject.DashboardActivity"
tools:showIn="#layout/toolbar">
<FrameLayout
android:id="#+id/dashframe"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<LinearLayout
android:clipToPadding="false"
android:gravity="center"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:id="#+id/dash_settings"
android:foreground="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:layout_width="160dp"
android:layout_height="190dp"
android:layout_margin="10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<ImageView
android:layout_width="64dp"
android:layout_height="64dp"
android:background="#drawable/bg_circle1"
android:src="#drawable/ic_settingspicture"
android:padding="10dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:layout_marginTop="10dp"
android:text="View your settings"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#color/lightgray"
android:layout_margin="10dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Follow along with guided tutorials"
android:padding="5dp"
android:textColor="#android:color/darker_gray"/>
</LinearLayout>
Replace
Fragment fragment1 = new SettingsViewFragment();
With this
Fragment fragment1 = new SettingsViewFragment();
FragmentTransaction fragmentTransaction=getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.Main_Layout,fragment1);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
Change Fragment fragment1 = new SettingsViewFragment (); by Toast.makeText (mActivity, "onCLick", Toast.LENGTH_LONG) .show ();
//if show toast The problem is not the onClick, the problem is when loading the fragment
Fragments should be instantiated with the newInstance() static method.
cd1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Fragment settingsFragment = SettingsFragment.newInstance();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.contentView, settingsFragment);
fragmentTransaction.commit();
}
});
In the SettingsFragment
public static SettingsFragment newInstance() {
return new SettingsFragment();
}
XML for content_main
LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical">
<android.support.v7.widget.CardView
android:id="#+id/dash_settings"
android:layout_width="match_parent"
android:layout_height="wrap_content"
...
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView
android:id="#+id/dash_profile"
android:layout_width="match_parent"
android:layout_height="wrap_content"
...
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView
android:id="#+id/dash_activity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
...
</android.support.v7.widget.CardView>
<FrameLayout
android:id="#+id/contentView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
</FrameLayout>
</LinearLayout>
This will transact the fragment into the FrameLayout that is positioned below the CardViews. Now this is probably not ideal, you would most likely want to launch a new activity that will host the fragment but this should work. Unless this is already in some Activity that hosts the fragment. But the key code is in the onClick.

Activity is hidden by fragment, it is not useable

i have builded an app that works perfectly on android with api higer than 21. The problem is that this instruction of my code:
mFragmentTransaction.replace(R.id.content_frame, new TabFragment()).commit();
Works in different way on API less then 21.
On Api less then 21 the new fragment hide the previus activity, so that i can't click on my Floating Action Button.
Here are two images that explain in abetter way my problem.
API HIGER THAN 21
API LESS THAN 21
So my question is: How can i have the same result in API less then 21 that i have on API Higer then 21?
Here is the affected part of the Main Activity Code:
public class MainActivity extends AppCompatActivity {
public static AppDataBase appDataBase;
public static UserDataBase userDataBase;
static FragmentManager mFragmentManager;
static FragmentTransaction mFragmentTransaction;
private DrawerLayout myDrawerLayout;
final String TXT_MAINACTVT_USER_HAVE_NOT_ADDED_CONSOLE = "Add a console!";
TextView currentConsole;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
appDataBase = new AppDataBase(this);
userDataBase = new UserDataBase(this);
myDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
currentConsole = (TextView) findViewById(R.id.txt_Mainactvt_currentConsole);
currentConsole.setText(TXT_MAINACTVT_USER_HAVE_NOT_ADDED_CONSOLE);
tabLayoutManagement();
floatingActionButtonManagement();
leftDrawerMenuManagement();
rigthDrawerMenuManagement();
populateMyConsole();
}
void tabLayoutManagement() {
mFragmentManager = getSupportFragmentManager();
mFragmentTransaction = mFragmentManager.beginTransaction();
mFragmentTransaction.replace(R.id.content_frame, new TabFragment()).commit();
}
// Floating Action Button
private void floatingActionButtonManagement() {
FloatingActionButton fab_addGame = (FloatingActionButton)findViewById(R.id.fab_AddGame);
fab_addGame.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
/*
The currentConsole TextView is used to show at the user wich console is selected.
We use it to have a strng that conteins the selected console.
Call the method that manage the click event of the FloatingActionButton. We pass the console name.
*/
String currentConsoleName = currentConsole.getText().toString();
floatingActionButtonClickEvent(currentConsoleName);
}
});
}
private void floatingActionButtonClickEvent(String currentConsoleName) {
/*
Check if user have added a console. If he did start a menu for adding games, else start an
error message
*/
if (!currentConsoleName.equals(TXT_MAINACTVT_USER_HAVE_NOT_ADDED_CONSOLE)) {
popUpViewAddGameBuild(currentConsoleName);
}
else
mySimpleAlertDialogMethod("Attention!", "Before you enter game, you must enter a console.", true, true);
}
private void popUpViewAddGameBuild(String currentConsoleName) {
/*
Build the view that show the menu for adding games.
*/
LayoutInflater inflater = this.getLayoutInflater();
View popupView = inflater.inflate(R.layout.popupview_addgame, null);
PopupWindow popupWindow = new PopupWindow(
popupView,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT);
popupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
popupWindow.setFocusable(true);
popupWindow.showAtLocation(popupView, 0, 0, 0);
}
Here is the TabLayout Class:
public class TabFragment extends Fragment {
public static TabLayout tabLayout;
public static ViewPager viewPager;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View x = inflater.inflate(R.layout.tab_layout, null);
tabLayout = (TabLayout) x.findViewById(R.id.tabs);
viewPager = (ViewPager) x.findViewById(R.id.viewpager);
viewPager.setAdapter(new MyAdapter(getChildFragmentManager()));
tabLayout.post(new Runnable() {
#Override
public void run() {
tabLayout.setupWithViewPager(viewPager);
}
});
return x;
}
public class MyAdapter extends FragmentPagerAdapter {
public int position;
public MyAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position){
case 0 :
return new DesireFragment();
case 1 :
return new BuyedFragment();
case 2 :
return new StartedFragment();
case 3 :
return new FinishedFragment();
case 4 :
return new AllTrophiesFragment();
}
return null;
}
#Override
public int getCount() {
return 5;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position){
case 0 :
return "Desire";
case 1 :
return "Buyed";
case 2 :
return "Started";
case 3 :
return "Finished";
case 4 :
return "AllTrophies";
}
return null;
}
}
}
There is the layout of the MainActivity:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:layout_gravity="end"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorPrimary"
android:id="#+id/toolbar"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:navigationIcon="#drawable/ic_menu_white_24dp"
app:title="MyGames">
<Button
android:id="#+id/btnOpenRigthDrawer"
android:background="#drawable/ic_filter_list_white_24dp"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginRight="10dp"
android:layout_gravity="right" />
<Button
android:id="#+id/btnOpenOptions"
android:background="#drawable/ic_settings_white_24dp"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginRight="17dp"
android:layout_gravity="right" />
</android.support.v7.widget.Toolbar>
</RelativeLayout>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollIndicators="bottom">
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:backgroundTint="#color/colorPrimary"
app:borderWidth="0dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="30dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="#+id/txt_Mainactvt_currentConsole"
android:layout_gravity="center_horizontal|top"
android:layout_marginTop="50dp"/>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab_AddGame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="17dp"
android:layout_marginRight="17dp"
android:src="#drawable/ic_mode_edit_white_24dp"
android:layout_gravity="bottom|right"
android:background="#color/colorPrimary" />
</FrameLayout>
<include
layout="#layout/drawer_left"
android:id="#+id/layLeft"
android:layout_gravity="start"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"/>
<include
layout="#layout/drawer_rigth"
android:id="#+id/layRigth"
android:layout_gravity="end"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:scrollbars="vertical"
/>
</android.support.v4.widget.DrawerLayout>
And here is the layout code of the TabLayout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="wrap_content">
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
app:tabGravity="fill"
app:tabMode="scrollable"
android:background="#color/colorPrimary"
app:tabIndicatorColor="#android:color/holo_orange_dark"
app:tabSelectedTextColor="#android:color/holo_orange_dark"
app:tabTextColor="#android:color/white"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
</android.support.design.widget.TabLayout>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager>
You replace the content of your FrameLayout with an Fragment. this leads to your strange result.
Add a Layout to your Framelayout instead and use it as your FragmentContainer:
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:backgroundTint="#color/colorPrimary"
app:borderWidth="0dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/content_frame"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="30dp"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="#+id/txt_Mainactvt_currentConsole"
android:layout_gravity="center_horizontal|top"
android:layout_marginTop="50dp"/>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab_AddGame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="17dp"
android:layout_marginRight="17dp"
android:src="#drawable/ic_mode_edit_white_24dp"
android:layout_gravity="bottom|right"
android:background="#color/colorPrimary" />
</FrameLayout>
Try to place your FrameLayout with this button to the end of layout

Why am I getting the error: java.lang.RuntimeException: java.lang.IllegalStateException: RecyclerView has no LayoutManager on (HelpActivity.java:28)

I'm developing a material design app. I want to display a list using RecyclerView in HelpActivity.
The problem is that I'm getting the following errors: java.lang.RuntimeException: java.lang.IllegalStateException: RecyclerView has no LayoutManager on line (HelpActivity.java:28).
Here's HelpActivity.java file's code:
public class HelpActivity extends AppCompatActivity {
public RecyclerView mRecyclerView;
public RecyclerView.LayoutManager mLayoutManager;
public RecyclerView.Adapter mAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_help);
mRecyclerView = (RecyclerView) findViewById(R.id.helpActivityContent);
// use a linear layout manager
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(layoutManager);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
mRecyclerView.setHasFixedSize(true);
mAdapter = new HelpContentAdapter(helpContents);
mRecyclerView.setAdapter(mAdapter);
initializeData();
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitleTextColor(Color.parseColor("#2196F3"));
setSupportActionBar(toolbar);
/*final Drawable upArrow = ContextCompat.getDrawable(this, R.drawable.abc_ic_ab_back_mtrl_am_alpha);
upArrow.setColorFilter(getResources().getColor(R.color.colorAccent), PorterDuff.Mode.SRC_ATOP);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeAsUpIndicator(upArrow);*/
/*FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});*/
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
class HelpActivityContent {
String option;
String subOption;
int icon;
HelpActivityContent(String option, String subOption, int icon) {
this.option = option;
this.subOption = subOption;
this.icon = icon;
}
}
public List<HelpActivityContent> helpContents;
// This method creates an ArrayList that has three Person objects
// Checkout the project associated with this tutorial on Github if
// you want to use the same images.
private void initializeData(){
helpContents = new ArrayList<>();
helpContents.add(new HelpActivityContent("123", "", R.drawable.ic_action_a));
helpContents.add(new HelpActivityContent("123", "", R.drawable.ic_action_b));
helpContents.add(new HelpActivityContent("321", "111", R.drawable.ic_action_c));
helpContents.add(new HelpActivityContent("1", "2", R.drawable.ic_action_d));
}
public class HelpContentAdapter extends RecyclerView.Adapter<HelpContentAdapter.HelpContentViewHolder>{
public class HelpContentViewHolder extends RecyclerView.ViewHolder {
TextView option;
TextView subOption;
ImageView icon;
HelpContentViewHolder(View itemView) {
super(itemView);
option = (TextView)itemView.findViewById(R.id.option);
subOption = (TextView)itemView.findViewById(R.id.subOption);
icon = (ImageView)itemView.findViewById(R.id.optionIcon);
}
}
List<HelpActivityContent> helpContents;
HelpContentAdapter(List<HelpActivityContent> helpContents){
this.helpContents = helpContents;
}
#Override
public int getItemCount() {
return helpContents.size();
}
#Override
public HelpContentViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.content_help, viewGroup, false);
HelpContentViewHolder pvh = new HelpContentViewHolder(v);
return pvh;
}
#Override
public void onBindViewHolder(HelpContentViewHolder helpContentViewHolder, int i) {
helpContentViewHolder.option.setText(helpContents.get(i).option);
helpContentViewHolder.subOption.setText(helpContents.get(i).subOption);
helpContentViewHolder.icon.setImageResource(helpContents.get(i).icon);
}
#Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
case android.R.id.home:
supportFinishAfterTransition();
return true;
}
return super.onOptionsItemSelected(item);
}
}
Here's content_help.xml file's code:
<?xml version="1.0" encoding="utf-8"?>
<!-- A RecyclerView with some commonly used attributes -->
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/helpActivityContent"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:showIn="#layout/activity_help"
tools:context="com.abc.xyz.HelpActivity">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/optionIcon"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginRight="16dp"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/option"
android:layout_toRightOf="#+id/optionIcon"
android:layout_alignParentTop="true"
android:textSize="30sp"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/subOption"
android:layout_toRightOf="#+id/optionIcon"
android:layout_below="#+id/option"
/>
</RelativeLayout>
</android.support.v7.widget.RecyclerView>
I'm unable to figure out what the problem is.
Please let me know.
Thanks in advance.
You cannot put your child elements directly inside the recycler view.
You need to create separate row layout like the one you create in listview.
Just remove the xml code written inside recycler view and insert it inside row_layout xml file and then inflate that row layout file inside your adapter instead.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:showIn="#layout/activity_help"
tools:context="com.abc.xyz.HelpActivity">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/optionIcon"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginRight="16dp"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/option"
android:layout_toRightOf="#+id/optionIcon"
android:layout_alignParentTop="true"
android:textSize="30sp"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/subOption"
android:layout_toRightOf="#+id/optionIcon"
android:layout_below="#+id/option"
/>
</RelativeLayout>
Just create separate file for row_layout containing above content and inflate it like below inside your oncreateviewholder:
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.**<new_layout_you_will_create>**, viewGroup, false);
I just made a small change in your content_help.xml and it works fine for me..
content_help.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:showIn="#layout/activity_help"
tools:context="com.abc.xyz.HelpActivity">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/optionIcon"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginRight="16dp"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/option"
android:layout_toRightOf="#+id/optionIcon"
android:layout_alignParentTop="true"
android:textSize="30sp"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/subOption"
android:layout_toRightOf="#+id/optionIcon"
android:layout_below="#+id/option"
/>
If you are using the recyclerview in activity_help.xml, no need to use the same for your row-content.
Hope this will solve your problem

Can't get Admob to show on multiple layouts?

I am trying to get Admob to display on my layout_one.xml and layout_two and can't get it to show. This app has a lot of swipe left and right and I want to display one ad over both layouts
Here are all my xml layouts:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/pager">
</android.support.v4.view.ViewPager>
layout_one.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/res-auto"
android:id="#+id/relative_one"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
android:focusable="true"
android:focusableInTouchMode="true"
android:orientation="vertical">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Copy"
android:id="#+id/Copy"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:layout_alignParentEnd="false"
android:layout_alignParentStart="false"
android:textSize="30sp"
android:onClick="onClickCopy"/>
<EditText
android:layout_width="300dp"
android:layout_height="50dp"
android:id="#+id/stringCopy"
android:layout_above="#+id/Copy"
android:layout_centerHorizontal="true"
android:layout_marginBottom="70dp"
android:textSize="30sp"
android:inputType="text"
android:gravity="left|top"
android:background="#ffffff" />
<com.google.android.gms.ads.AdView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
ads:adSize="BANNER"
ads:adUnitId="#string/banner_ad_unit_id"/>
layout_two.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/relative_one"
android:background="#000000"
android:focusable="true"
android:focusableInTouchMode="true"
android:orientation="vertical">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Paste"
android:id="#+id/Paste"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:layout_alignParentEnd="false"
android:layout_alignParentStart="false"
android:textSize="30sp"
android:onClick="onClickPaste"/>
<EditText
android:layout_width="300dp"
android:layout_height="50dp"
android:id="#+id/stringCopy"
android:layout_marginBottom="71dp"
android:textSize="30sp"
android:inputType="text"
android:gravity="left|top"
android:background="#ffffff"
android:layout_above="#+id/Paste"
android:layout_centerHorizontal="true" />
<!-- SHOULD I PUT ANOTHER ADVIEW IN THIS XML -->
</RelativeLayout>
Here is all my java classes:
MainActivity.java
public class MainActivity extends FragmentActivity {
//View Pager
ViewPager viewpager;
//AdView
AdView adView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewpager = (ViewPager)findViewById(R.id.pager);
PagerAdapter pAdapter = new PagerAdapter(getSupportFragmentManager());
viewpager.setAdapter(pAdapter);
}
public void onClickCopy(View v)
{
//Copy Text From layout_one to Clipboard
}
public void onClickPaste(View v)
{
//Paste Text From Clipboard
}
}
PagerAdapter.java
public class PagerAdapter extends FragmentPagerAdapter {
public PagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int arg0) {
switch (arg0) {
case 0:
return new FragmentOne();
case 1:
return new FragmentTwo();
default:
break;
}
return null;
}
#Override
public int getCount() {
return 2;
}
}
FragmentOne.java
public class FragmentOne extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.layout_one, container, false);
}
}
FragmentTwo.java
public class FragmentTwo extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.layout_two, container, false);
}
}
Where would I put this code so that when they swipe between layout_one and layout_two that the same ad will be displayed and not make a new ad request every time they change views?
//Display test Ads
adView = new AdView(this);
AdRequest request = new AdRequest.Builder()
.addTestDevice("DEVICE_ID").build();
adView.loadAd(request);
The standard pattern for doing this is to put your AdView either above or below your ViewPager and keep it static. That way you are not constantly requesting ads that you never get time to display.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
>
<android.support.v4.view.ViewPager
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:id="#+id/pager">
</android.support.v4.view.ViewPager>
<com.google.android.gms.ads.AdView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:adUnitId="yourAdUnitId"
android:id="#+id/adView">
</LinearLayout>
This way your Adview is outside your ViewPager and remains constant across all pages.
I use the following code to cache Admob in scroll Grid View:
public View getView(int position, View convertView, ViewGroup parent) {
if (position != adNum) {
...
} else {
if (mAdView == null) {
frameLayout = new FrameLayout(mContext);
mAdView = new AdView(mContext);
...
frameLayout.addView(mAdView);
} else {
frameLayout.removeView(mAdView);
frameLayout = new FrameLayout(mContext);
frameLayout.addView(mAdView);
}
return frameLayout;
}
}

Change the size of a fragment with a button

I'm trying to change the weight of "MapView" and "InfoContent" when i click on a button inside the mapview fragment. The mapView Fragment is defined in the PlaceholderFragment2 Java Class.
The first click should change the weight to a new value, while the second click should restore the old value.
XMl:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
tools:context=".MainActivity"
android:orientation="vertical"
>
<FrameLayout
android:id="#+id/TitleBar"
android:layout_width="fill_parent"
android:layout_height="50dp"
>
</FrameLayout>
<FrameLayout
android:id="#+id/MapView"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1">
</FrameLayout>
<FrameLayout
android:id="#+id/InfoTitleBar"
android:layout_width="fill_parent"
android:layout_height="170dp"
>
</FrameLayout>
<FrameLayout
android:id="#+id/InfoContent"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="0"
>
</FrameLayout></LinearLayout>
MainActivity.Java
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
PlaceholderFragment frg=new PlaceholderFragment();
PlaceholderFragment2 frg2=new PlaceholderFragment2();
PlaceholderFragment3 frg3=new PlaceholderFragment3();
PlaceholderFragment4 frg4=new PlaceholderFragment4();
FragmentManager manager=getFragmentManager();
FragmentTransaction transaction=manager.beginTransaction();
transaction.add(R.id.TitleBar, frg, "Frag_Top_tag");
transaction.add(R.id.MapView, frg2, "Frag_Middle_tag");
transaction.add(R.id.InfoTitleBar, frg3, "Frag_Bottom_tag");
transaction.add(R.id.InfoContent, frg4, "Frag_Content_tag");
transaction.commit();
}
And PlaceHolderFragment2.java
public static class PlaceholderFragment2 extends Fragment {
public PlaceholderFragment2() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.mapview, container,
false);
final Button button =
(Button) rootView.findViewById(R.id.zoomMap);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
buttonClicked(v);
}
});
return rootView;
}
I solved it, I put the fragment in linear layout, then in the main activity I created the object, when I click just change the size of the weight of the linear layout, cos' I do not need nor by the fragment transaction.
MainActivity
private Button button;
private LinearLayout layoutListView;
private LinearLayout.LayoutParams lpListView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_container);
button = (Button) findViewById(R.id.button);
layoutListView = (LinearLayout) findViewById(R.id.listTreeView);
lpListView = new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT);
lpListView.weight = 20;
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (lpListView.weight == 0) {
lpListView.weight = 20;
} else {
lpListView.weight = 0;
}
layoutListView.setLayoutParams(lpListView);
}
});
}
}
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="100"
android:orientation="horizontal"
android:weightSum="100" >
<LinearLayout
android:id="#+id/listTreeView"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="20"
android:orientation="horizontal" >
<fragment
android:id="#+id/fraglistView"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.example.ListTreeView" />
</LinearLayout>
<LinearLayout
android:id="#+id/fragbutton"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="80"
android:background="#F000" >
<fragment
android:id="#+id/fraglistRight"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.example.ListViewRight" />
</LinearLayout>
</LinearLayout>

Categories