findViewbyId in custom adapter returns null - android-adapter

I am trying to retrieve a textView in a custom Adapter but it is returning null for some reason. Can you guys explain why? am new to Android and am stuck here. I am also attaching the view the adapter is connecting to, its called profile_listitem.xml and contains the textView I want.
Thank you
AdapterProfile.xml
public AdapterProfiles(Context context,ArrayList<Profile> profilesArray)
{
super(context, R.layout.profile_listitem, profilesArray);
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
Profile p= getItem(position);
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.profile_listitem , parent, false);
}
TextView textAppName=(TextView)convertView.findViewById(R.id.textViewApp);
ToggleButton appStatus =(ToggleButton)convertView.findViewById(R.id.toggleAppStatus);
if(convertView.findViewById(R.id.textViewApp)==null)
Log.d("Profile","Profile is null");
textAppName.setText(p.getName());
appStatus.setChecked(p.isActive());
return convertView;
}
profile_listitem.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">
<TextView
android:layout_width="match_parent"
android:layout_height="48dp"
android:background="#color/background"
android:textColor="#color/blue"
android:textSize="36dp"
android:id="#+id/textViewAppName"/>
<ToggleButton
android:layout_width="72dp"
android:layout_height="48dp"
android:layout_alignParentEnd="true"
android:textColor="#color/white"
android:background="#color/blue"
android:id="#+id/toggleAppStatus"/>

Because you have used
R.id.textViewApp
instead of what you defined in the xml file i.e.
R.id.textViewAppName
TextView textAppName=(TextView)convertView.findViewById('R.id.textViewApp');

Related

How to replace one fragment with another on button click in Xamarin.Android?

I want to have the following screen:
When I click IMAGE 1 and IMAGE 2 buttons I want in IMAGE ZONE to appear Image1.jpg and Image2.jpg respectively. I want Image1.jpg and Image2.jpg to be in different fragments and replace those fragments on button click rather than changing simply the android:src of the ImageView in IMAGE ZONE on button click. I want Image1.jpg to be the first image to appear when opening the activity. I can't find how to do that with fragments in Xamarin.Android
You can create two Fragment and its xml first.
FragmentOne :
public class Fragment1 : Android.Support.V4.App.Fragment
{
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Create your fragment here
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// Use this to return your custom view for this Fragment
return inflater.Inflate(Resource.Layout.layoutFragment1, container, false);
//return base.OnCreateView(inflater, container, savedInstanceState);
}
}
and its xml :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/fragment1">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:src="#drawable/th2"/>
</LinearLayout>
FragementTwo :
public class Fragment2 : Android.Support.V4.App.Fragment
{
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Create your fragment here
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// Use this to return your custom view for this Fragment
return inflater.Inflate(Resource.Layout.layoutFragment2, container, false);
//return base.OnCreateView(inflater, container, savedInstanceState);
}
}
and its xml :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/fragment2">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:src="#drawable/th2"/>
</LinearLayout>
Then in MainActivity , you can set its xml as follow :
<?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">
<LinearLayout
android:gravity="center_horizontal"
android:layout_width="match_parent"
android:layout_height="80dip"
android:orientation="horizontal">
<Button
android:id="#+id/buttonone"
android:layout_width="150dip"
android:layout_height="80dip"
android:text="FragmentOne"/>
<Button
android:id="#+id/buttontwo"
android:layout_width="150dip"
android:layout_height="80dip"
android:text="FragmentTwo"/>
</LinearLayout>
<RelativeLayout
android:id="#+id/containerView"
android:layout_width="match_parent"
android:layout_height="430dip">
</RelativeLayout>
</LinearLayout>
Finally , in MainActivity.cs implement this function :
public class MainActivity : AppCompatActivity
{
Android.Support.V4.App.Fragment fragmentOne;
Android.Support.V4.App.Fragment fragmentTwo;
Android.Support.V4.App.FragmentTransaction fragmentManager;
[Obsolete]
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
Button buttonone = FindViewById<Button>(Resource.Id.buttonone);
buttonone.Click += Buttonone_Click;
Button buttontwo = FindViewById<Button>(Resource.Id.buttontwo);
buttontwo.Click += Buttontwo_Click;
fragmentOne = new Fragment1();
fragmentTwo = new Fragment2();
fragmentManager = SupportFragmentManager.BeginTransaction();
fragmentManager.Add(Resource.Id.containerView, fragmentOne);
//adding first fragment when entering activity
fragmentManager.Commit();
}
private void Buttonone_Click(object sender, System.EventArgs e)
{
//throw new System.NotImplementedException();
Console.WriteLine("Buttonone_Click");
fragmentManager = SupportFragmentManager.BeginTransaction();
// replace to be the first fragment
fragmentManager.Replace(Resource.Id.containerView, fragmentOne);
fragmentManager.Commit();
}
private void Buttontwo_Click(object sender, System.EventArgs e)
{
//throw new System.NotImplementedException();
Console.WriteLine("Buttontwo_Click");
fragmentManager = SupportFragmentManager.BeginTransaction();
// replace ro be the second fragment
fragmentManager.Replace(Resource.Id.containerView, fragmentTwo);
fragmentManager.Commit();
}
}
The effect as follow :

Android Navigation Component 'Up button' opens drawer navigation

I am trying to implement a simple navigation using Navigation Component with navigation graph and navigation controller.
I have my MainActivity with actionbar with hamburger icon and app title, a drawer navigation and content area.
Content area is where I display different fragments.
Content area is first loaded with my homescreenFragment containing 4 buttons (news, events, timetable, profile) - each of them loads fragment into my MainActivity's Content area.
It works fine, the only problem is the following:
When I press news button and navigate from my homescreen to my NewsFragment it loads fragment OK and changes actionbar title to News. Hamburger icon is changed to 'Up button' icon, but when I press on it, application opens Navigation Drawer as if I press on the hamburger icon instead of navigating me back to the home screen.
How do I make Up button to go up and not showing left navigation drawer ?
here is my MainActivity.java:
import android.os.Bundle;
import android.support.design.widget.NavigationView;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.NavigationUI;
public class MainActivity extends AppCompatActivity {
Toolbar m_toolbar;
DrawerLayout m_drawer;
ActionBarDrawerToggle m_toggle;
NavigationView m_navigationView;
NavController m_navController;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
m_toolbar = findViewById(R.id.toolbar);
setSupportActionBar(m_toolbar);
m_drawer = findViewById(R.id.drawer_layout);
m_navigationView = findViewById(R.id.nav_drawer_view);
m_navController = Navigation.findNavController(this, R.id.content);
m_toggle = new ActionBarDrawerToggle(
this, m_drawer, m_toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
m_drawer.addDrawerListener(m_toggle);
//m_toggle.syncState();
//connect actionbar icon and drawer with nav controller
NavigationUI.setupWithNavController(m_navigationView, m_navController);
NavigationUI.setupActionBarWithNavController(this, m_navController);
NavigationUI.setupActionBarWithNavController(this, m_navController, m_drawer);
}
#Override
public boolean onSupportNavigateUp() {
return Navigation.findNavController(this, R.id.nav_drawer_view).navigateUp() || super.onSupportNavigateUp();
}
#Override
public void onBackPressed() {
DrawerLayout drawer = findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
}
my activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout 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:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<LinearLayout
android:orientation="vertical"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
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:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:name="androidx.navigation.fragment.NavHostFragment"
app:navGraph="#navigation/nav_graph"
app:defaultNavHost="true"/>
</FrameLayout>
</LinearLayout>
<android.support.design.widget.NavigationView
android:id="#+id/nav_drawer_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
navigation graph:
<?xml version="1.0" encoding="utf-8"?>
<navigation 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:id="#+id/nav_graph"
app:startDestination="#id/homeScreenFragment">
<fragment
android:id="#+id/homeScreenFragment"
android:name="com.mysample.meganews.Fragments.HomeScreenFragment"
android:label="#string/app_name"
tools:layout="#layout/home_screen_fragment" >
<action
android:id="#+id/action_to_news"
app:destination="#id/newsFragment"
app:enterAnim="#anim/nav_default_enter_anim"
app:exitAnim="#anim/nav_default_exit_anim" />
<action
android:id="#+id/action_to_events"
app:destination="#id/eventsFragment"
app:enterAnim="#anim/nav_default_pop_enter_anim"
app:exitAnim="#anim/nav_default_pop_exit_anim" />
</fragment>
<fragment
android:id="#+id/newsFragment"
android:name="com.mysample.meganews.Fragments.NewsFragment"
android:label="#string/hs_title_news"
tools:layout="#layout/news_fragment" />
<fragment
android:id="#+id/eventsFragment"
android:name="com.mysample.meganews.Fragments.EventsFragment"
android:label="events_fragment"
tools:layout="#layout/events_fragment" />
</navigation>
HomeScreenFragment.java file:
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
/**
* A simple {#link Fragment} subclass.
*/
public class HomeScreenFragment extends Fragment {
public HomeScreenFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.home_screen_fragment, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
RelativeLayout rl_news = view.findViewById(R.id.ll_news_btn);
RelativeLayout rl_events = view.findViewById(R.id.ll_events_btn);
rl_news.setOnClickListener(Navigation.createNavigateOnClickListener(R.id.action_to_news));
rl_events.setOnClickListener(Navigation.createNavigateOnClickListener(R.id.action_to_events));
}
}
build.gradle file:
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.mysample.meganews"
minSdkVersion 16
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:design:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.android.support:support-v4:28.0.0'
implementation 'android.arch.lifecycle:extensions:1.1.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'android.arch.navigation:navigation-fragment:1.0.0-alpha11'
implementation 'android.arch.navigation:navigation-ui:1.0.0-alpha11'
}
This problem was due to mixing of different APIs . Here is the right code:
activity_main.xml:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/colorPrimary"
android:theme="#style/ThemeOverlay.AppCompat.Dark" />
<fragment
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:name="androidx.navigation.fragment.NavHostFragment"
app:navGraph="#navigation/nav_graph"
app:defaultNavHost="true"/>
</LinearLayout>
<com.google.android.material.navigation.NavigationView
android:id="#+id/nav_drawer_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer" />
</androidx.drawerlayout.widget.DrawerLayout>
MainActivity.java:
import android.os.Bundle;
import com.google.android.material.navigation.NavigationView;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.lifecycle.ViewModelProviders;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.NavigationUI;
import android.view.MenuItem;
import android.view.ViewParent;
public class MainActivity extends AppCompatActivity
{
private Toolbar mToolbar;
private DrawerLayout mDrawer;
private ActionBarDrawerToggle mToggle;
private NavigationView mNavigationView;
private NavController mNavController;
private MainViewModel mViewModel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mViewModel = ViewModelProviders.of(this).get(MainViewModel.class);
setupNavigation();
}
private void setupNavigation()
{
mToolbar = findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mDrawer = findViewById(R.id.drawerLayout);
mNavigationView = findViewById(R.id.nav_drawer_view);
mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
// // we need this line to handle the navigation
// boolean handled = NavigationUI.onNavDestinationSelected(menuItem, mNavController);
// if (handled) {
// ViewParent parent = mNavigationView.getParent();
// if (parent instanceof DrawerLayout) {
// ((DrawerLayout) parent).closeDrawer(mNavigationView);
// }
// }
return true;
}
});
mNavController = Navigation.findNavController(this, R.id.content);
NavigationUI.setupActionBarWithNavController(this, mNavController, mDrawer);
// Tie nav graph to items in nav drawer
NavigationUI.setupWithNavController(mNavigationView, mNavController);
}
#Override
public boolean onSupportNavigateUp() {
//return Navigation.findNavController(this, R.id.content).navigateUp();
//return mNavController.navigateUp() || super.onSupportNavigateUp();
return NavigationUI.navigateUp(mNavController, mDrawer);
}
#Override
public void onBackPressed() {
if (mDrawer.isDrawerOpen(GravityCompat.START)) {
mDrawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
I had the same issue and fixed it with below workaround.
mNavController.addOnDestinationChangedListener(new NavController.OnDestinationChangedListener() {
#Override
public void onDestinationChanged(#NonNull NavController controller,
#NonNull NavDestination destination, #Nullable Bundle arguments) {
if (mAppBarConfiguration.getTopLevelDestinations().contains(destination.getId())) {
mToggle.setDrawerIndicatorEnabled(true);
} else {
mToggle.setDrawerIndicatorEnabled(false);
}
}
});
Also make sure to set the click listener to ActionBarDrawerToggle as below.
mToggle.setToolbarNavigationClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mActivity.onBackPressed();
}
});
Navigation handle this by default you do not have to explicitly handle listener for this.
In your activity override "onSupportNavigationUp"
override fun onSupportNavigateUp(): Boolean {
return NavigationUI.navigateUp(navController, drawer_layout)
}
and do above. It will handle back button and hamburger icon by default.

Xamarin.Android: Changing a specific value in a list during runtime

I have a simple Xamarin.Android-App.
On the Activity of this app, there is a list displayed. Please see following MyActivity.axml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android ="http://schemas.android.com/apk/res/android"
android:orientation ="vertical"
android:layout_width ="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width ="match_parent"
android:layout_height="wrap_content"
android:text ="Click Me"
android:layout_marginTop ="20dp"
android:layout_marginLeft ="25dp"
android:layout_marginRight ="25dp"
android:id="#+id/button" />
<Space
android:layout_width="match_parent"
android:layout_height="25dp"
android:id="#+id/space" />
<ListView
android:minWidth="25px"
android:minHeight="25px"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/list" />
</LinearLayout>
One row of this list contains simply two entries, please see ListRow.axml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:id="#+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft ="5dp"
android:layout_marginTop ="10dp"
android:layout_marginBottom="10dp"
android:layout_marginRight ="5dp" />
<TextView
android:id="#+id/value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft ="5dp"
android:layout_marginTop ="10dp"
android:layout_marginBottom="10dp"
android:layout_marginRight ="5dp" />
</RelativeLayout>
So the code-behind of that activity looks like the following:
public class MyActivity : Activity
{
List<Entry> List = null;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.MyActivity);
List = PopulateList();
var lv = FindViewById<ListView>(Resource.Id.list);
var adapter = new ListAdapter(this, Resource.Layout.List, List);
lv.Adapter = adapter;
FindViewById<Button>(Resource.Id.button).Click += OnButtonClick;
}
}
For the sake of completeness, here is the code for my ListAdapter.cs-class:
class ListAdapter : ArrayAdapter
{
List<Entry> List;
public ListAdapter(Context Context, int ListId, List<Entry> List) : base(Context, ListId, List)
{
this.List = List;
}
public override int Count
{
get { return List.Count; }
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
View v = convertView;
if (v == null)
{
LayoutInflater inflater = (LayoutInflater)Context.GetSystemService(Context.LayoutInflaterService);
v = inflater.Inflate(Resource.Layout.List, parent, false);
}
v.FindViewById<TextView>(Resource.Id.name).Text = List[position].Name;
v.FindViewById<TextView>(Resource.Id.value).Text = "Original Value";
return v;
}
}
So my question now is the following: Assuming that there is more than one item within that List. On click of the button, I want to change one specific text within that list. Let's say of the second entry in the list the (Resource.Id.value).Text (which now says "Original Value") to "Changed Value" or something like that. But only of the second one. All the other items should stay the same.
Please see following example of output aimed, maybe it's easier to understand what I am trying to do:
Name Value
- - - - - - - - - - - - - - - -
No.1 Original Value
No.2 Original Value
No.3 Original Value
[Button Click]
Name Value
- - - - - - - - - - - - - - - -
No.1 Original Value
No.2 Changed Value
No.3 Original Value
Can anyone maybe help me / tell me how to do this? What does my private void OnButtonClick(object sender, EventArgs e)-method have to look like? How can I access a single entry in that list?
Thanks in advance for all answers and best regards
you could add a method in adapter to notifyDataSetChanged(); :
class ListAdapter : ArrayAdapter
{
List<Entry> List;
private int ItemPositionToChange = -1;
public ListAdapter(Context Context, int ListId, List<Entry> List) :
base(Context, ListId, List)
{
this.List = List;
}
//this method to let adapter notify
public void ChangeItemValue(int position)
{
ItemPositionToChange = position;
NotifyDataSetChanged();
}
public override int Count
{
get { return List.Count; }
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
View v = convertView;
if (v == null)
{
LayoutInflater inflater =
(LayoutInflater)Context.GetSystemService(Context.LayoutInflaterService);
v = inflater.Inflate(Resource.Layout.List, parent, false);
}
v.FindViewById<TextView>(Resource.Id.name).Text = List[position].Name;
//change the item value according to your needs
if(position == ItemPositionToChange ){
v.FindViewById<TextView>(Resource.Id.value).Text = "Changed Value";
}else{
v.FindViewById<TextView>(Resource.Id.value).Text = "Original Value";
}
return v;
}
}
then in your button click listener :
void OnButtonClick(object sender, EventArgs e)
{
//positionToChange is which item you want to change
adapter.ChangeItemValue(positionToChange);
}
I'm not too familiar with the Entry class, but it seems to have a Text property.
Assuming you know the index of the string (myIndex below):
private void OnButtonClick(object sender, EventArgs e) {
List[myIndex].Text = "Changed Value";
adapter.notifyDataSetChanged();
}

Cannot remove Padding from Tabs when using Custom views with Tab Layout

I have added a Relative Layout in Custom View and have added this in Tab Layout. I am using a white background for tabs and have not applied any padding in tabs custom layout. But then also I am getting padding on tabs due to which I am shown some grey background within tabs as if android is internally applying padding to tabs. I am trying to display three text views which I am able to do but one of them is truncating because of padding applied to tabs. Also I want to have consistent background color for tabs.
Here is my code:
activity_home.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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:fitsSystemWindows="true"
tools:context="com.customtablayoutapplication.HomeActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
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:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_home" />
</android.support.design.widget.CoordinatorLayout>
fragment_home.xml:
<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"
android:theme="#style/AppTheme.AppBarOverlay"
tools:context="com.customtablayoutapplication.HomeFragment"
tools:showIn="#layout/activity_home">
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabGravity="fill"
app:tabMode="fixed" />
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</LinearLayout>
custom_tab.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:background="#android:color/white"
android:layout_height="match_parent"
android:layout_gravity="center">
<TextView
android:id="#+id/total_request_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:text="12"
android:textAllCaps="false"
android:visibility="gone"
android:textColor="#color/colorPrimaryDark"
android:textSize="12sp" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:fitsSystemWindows="true"
android:gravity="center">
<TextView
android:id="#+id/request_status"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="New Request"
android:textAllCaps="false"
android:textColor="#color/colorPrimaryDark"
android:textSize="12sp" />
<TextView
android:id="#+id/badge_icon"
android:layout_width="13dp"
android:layout_height="13dp"
android:layout_alignParentRight="true"
android:layout_alignTop="#id/request_status"
android:layout_marginLeft="-3dp"
android:layout_marginTop="15dp"
android:background="#drawable/circular_text_background"
android:clickable="false"
android:visibility="gone" />
</RelativeLayout>
</RelativeLayout>
HomeFragment.java:
package com.customtablayoutapplication;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
/**
* A placeholder fragment containing a simple view.
*/
public class HomeFragment extends Fragment {
private ViewPager viewPager;
private TabLayout tabLayout;
public HomeFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_home, container, false);
viewPager = (ViewPager) view.findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) view.findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
setUpTabIcons();
return view;
}
private void setUpTabIcons() {
RelativeLayout tabNewRequest= (RelativeLayout) LayoutInflater.from(getActivity()).inflate(R.layout.custom_tab, null);
TextView tabNewRequesttxt = (TextView) tabNewRequest.findViewById(R.id.request_status);
tabNewRequesttxt.setText("New Request");
tabLayout.getTabAt(0).setCustomView(tabNewRequest);
RelativeLayout tabInProgress= (RelativeLayout) LayoutInflater.from(getActivity()).inflate(R.layout.custom_tab, null);
TextView tabInProgresstxt = (TextView) tabInProgress.findViewById(R.id.request_status);
tabInProgresstxt.setText("In Progress");
tabLayout.getTabAt(1).setCustomView(tabInProgress);
RelativeLayout tabWorkDone= (RelativeLayout) LayoutInflater.from(getActivity()).inflate(R.layout.custom_tab, null);
TextView tabWorkDonetxt = (TextView) tabWorkDone.findViewById(R.id.request_status);
tabWorkDonetxt.setText("Work Done");
tabLayout.getTabAt(2).setCustomView(tabWorkDone);
RelativeLayout tabDelivered= (RelativeLayout) LayoutInflater.from(getActivity()).inflate(R.layout.custom_tab, null);
TextView tabDeliveredtxt = (TextView) tabDelivered.findViewById(R.id.request_status);
tabDeliveredtxt.setText("Delivered");
tabLayout.getTabAt(3).setCustomView(tabDelivered);
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getChildFragmentManager());
adapter.addFragment(new NewRequestFragment(), "New Request");
adapter.addFragment(new InProgressFragment(), "In Progress");
adapter.addFragment(new WorkDoneFragment(), "Work Done");
adapter.addFragment(new DeliveredFragment(), "Delivered");
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
}
Fixed Tab are having grey background arround white background:
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
android:layout_width="210dp"
android:layout_height="28dp"
android:layout_centerInParent="true"
android:background="#drawable/bg_forum_tab"
app:tabIndicatorColor="#color/colorBtnBg"
app:tabIndicatorHeight="0dp"
app:tabPaddingBottom="-1dp"
app:tabPaddingEnd="-1dp"
app:tabPaddingStart="-1dp"
app:tabPaddingTop="-1dp"
app:tabSelectedTextColor="#color/colorBtnBg"
app:tabTextColor="#color/colorWhite" />
Set tabPaddingStart/tabPaddingEnd/tabPaddingTop/tabPaddingBottom like this.
It worked for me:
In your TabLayout you have to set tabPaddingEnd and tabPaddingStart to 0dp.
In your custom view you have to set the layout_width and layout_height to match_parent in order to fill all space with your custom color.
The TabLayout:
<android.support.design.widget.TabLayout
android:id="#+id/tl_dashboard"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_alignParentBottom="true"
app:tabGravity="fill"
app:tabIndicatorColor="#color/colorRed"
app:tabMode="fixed"
app:tabPaddingStart="0dp"
app:tabPaddingEnd="0dp"/>
And custom view:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--Your widgets-->
</RelativeLayout>
Through XML you can remove only the left and right paddings like that:
app:tabPaddingEnd="0dp"
app:tabPaddingStart="0dp"
Notice, that this way doesn`t work for TOP and BOTTOM paddings, but I find next solution:
When you use custom views as tab item, you need to set LayoutParams to the view and set paddings 0.
for (int i = 0; i < tabLayout.getTabCount(); i++) {
View tabView = LayoutInflater.from(context)
.inflate(LayoutInflater.from(this), R.layout.item_main_tabview, null, false);
tabView.setLayoutParams(new TableLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
tabView.setPadding(0, 0, 0, 0);
tabLayout.getTabAt(i).setCustomView(tabViewBinding.getRoot());
}
I solved this by setting the margin & padding of your custom view's parent to zero, when adding new tabs to tab layout.
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
lp.setMargins(0,0,0,0);
TabLayout.Tab newTab = mTabsBottom.newTab().setCustomView(R.layout.view_custom_tab);
setupTabParentLayout(newTab.getCustomView(), lp);
..
..
..
private void setupTabParentLayout(View customView, LinearLayout.LayoutParams lp) {
LinearLayout tabParent = (LinearLayout) customView.getParent();
tabParent.setLayoutParams(lp);
tabParent.setPadding(0,0,0,0);
}
Trick here was to use LinearLayout.LayoutParams for custom view's parent.
I know this is an old question but this can help someone else. Padding start and padding end is not removing space between tabs. Solution is :
android:clipToPadding="true"
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="#color/colorGrayBackground"
app:tabGravity="fill"
app:tabPaddingStart="0dp"
app:tabPaddingEnd="0dp"
app:tabContentStart="0dp"
app:tabIndicatorHeight="0dp"
android:clipToPadding="true"
app:tabMode="fixed" />
Then you can set paddings to "0dp". Hope it helps someone.
In case you have tried many things and none of them did work, here is what I ended up doing: just setting
android:layout_height="20dp
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.viewpager.widget.ViewPager
android:layout_width="match_parent"
android:layout_gravity="bottom"
android:layout_height="130dp"/>
<com.google.android.material.tabs.TabLayout
android:layout_height="20dp"
android:layout_width="match_parent"
android:layout_gravity="bottom"
app:tabBackground="#drawable/tab_selector"
app:tabGravity="center"
app:tabIndicatorHeight="0dp"/>
</FrameLayout>
I create TabLayout from code and me help only this
for (int position = 0; position < mTabLayout.getTabCount(); position++) {
TabLayout.Tab tab = mTabLayout.getTabAt(position);
if (tab != null) {
ViewCompat.setPaddingRelative(tab.view, 0, 0, 0, 0);
}
}
<android.support.design.widget.TabLayout
android:id="#+id/tabview"
app:layout_constraintTop_toBottomOf="#+id/ivpromo"
android:layout_width="0dp"
app:tabMode="scrollable"
app:tabIndicatorHeight="0dp"
app:tabContentStart="0dp"
android:clipToPadding="true"
app:tabMaxWidth="45dp"
app:tabGravity="fill"
app:tabPaddingStart="0dp"
app:tabPaddingEnd="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:tabIndicatorColor="#android:color/transparent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toRightOf="#+id/tvcode"
android:layout_height="40dp"/>
First of all I've tried to use app:tabMinWidth="0dp"
Then I've tried dcanbatman's answer.
And it started to work only with both of these solutions:
app:tabPaddingStart="0dp"
app:tabPaddingEnd="0dp"
app:tabMinWidth="0dp"

How to add action bar to a DialogFragment?

How to add action bar to a DialogFragment? I found a way to style an activity to the way we require and then display it as a dialog as in the following link ActionBar in a DialogFragment I need to set an action bar on a proper DialogFragment. Is it possible?
As Up ActionBar action on DialogFragment
indicates: There is no way to attach an ActionBar to the DialogFragment even though you can set the theme of the DialogFragment it will not register as a ActionBar to it, Dialog.getActionBar() will always return null.
But there's always the cases that I really want to use DialogFragment(which contain ActionBar like style) instead of Activity. Just add a Layout that will look like an ActionBar into the DialogFragment's Layout
the following is the steps:
1) DialogFragment layout: about_dialog.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#color/white" >
<include android:id="#+id/fake_action_bar"
layout="#layout/fake_action_bar_with_backbotton" />
2) Implement a ActionBar like layout: fake_action_bar_with_backbotton.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/fake_action_bar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:minHeight="?attr/actionBarSize"
app:navigationIcon="#drawable/ic_menu_back"
android:background="#color/background_material_dark"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light" />
Note: the #drawable/ic_menu_back is copied from sdk\platforms\android-21\data\res\drawable-hdpi
3) Update the DialogFragment code
public class AboutDialogFragment extends DialogFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// use Theme_Holo_Light for full screen
// use Theme_Holo_Dialog for not full screen
// first parameter: DialogFragment.STYLE_NO_TITLE no title
setStyle(DialogFragment.STYLE_NO_FRAME, android.R.style.Theme_Holo_Light_DarkActionBar);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.about_dialog, container, false);
// set the listener for Navigation
Toolbar actionBar = (Toolbar) v.findViewById(R.id.fake_action_bar);
if (actionBar!=null) {
final AboutDialogFragment window = this;
actionBar.setTitle(R.string.about_title);
actionBar.setNavigationOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
window.dismiss();
}
});
}
return v;
}
}
Wish it can help!