I have the current working code, which add
mNavigationView = findViewById(R.id.navigation)
mDrawerLayout = findViewById(R.id.drawerLayout)
val headerview : View = mNavigationView.getHeaderView(0)
mSettingsIcon = headerview.findViewById(R.id.settingsIcon)
mSettingsIcon.setOnClickListener {
// navigate other activity
}
I want to replace it using direct XML access that is available on Kotlin.
I tried the following:
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.navigation_header.*
mSettingsIcon.setOnClickListener {
// Handle Click
}
But I received the following error:
java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.my.app/com.my.app.MainActivity}:
java.lang.NullPointerException: Attempt to invoke virtual method 'void
android.widget.ImageButton.setOnClickListener(android.view.View$OnClickListener)'
on a null object reference (...) Caused by:
java.lang.NullPointerException: Attempt to invoke virtual method 'void
android.widget.ImageButton.setOnClickListener(android.view.View$OnClickListener)'
on a null object reference
I think that is because the ImageView Settings is located inside another XML (called Navigation Header) that is on XML like this:
inside activity_main.xml:
<com.google.android.material.navigation.NavigationView
android:id="#+id/mNavigationTab"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="#layout/navigation_header"
app:menu="#layout/navigation_items"/>
inside navigation_header.xml:
<ImageButton
android:id="#+id/mSettingsIcon"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="#drawable/icon_settings"
android:layout_marginTop="10sp"
android:layout_marginStart="20sp"
android:padding="0dp"/>
Does anyone knows how can I access using Kotlin direct access to XML components?
At first, You have to get HeaderView from NavigationView and then use below code to achieve this:
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.navigation_header.view.*
val headerView = mNavigationTab.getHeaderView(0)
headerView.mSettingsIcon.setOnClickListener {
// Handle Click
}
Related
I have the following TextView
<TextView
android:id="#+id/LoginlinkLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical center_horizontal"
android:autoSizeMaxTextSize="45sp"
android:autoSizeMinTextSize="15sp"
android:autoSizeStepGranularity="2sp"
android:text="#string/Loginlink"
android:textAlignment="center"
android:textSize="15sp"
android:onClick="loginlinkLabelonClick"
android:clickable="true"/>
And this function
fun loginlinkLabelonClick(context:Context)
{
val urlString="http://www.google.gr"
val intent = Intent(Intent.ACTION_VIEW,Uri.parse(urlString)) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
intent.`package`="com.android.chrome"
try
{
context.startActivity(intent)
}
catch(ex:ActivityNotFoundException)
{
intent.`package`= null
context.startActivity(intent)
}
}
The error message:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.reviewer.reviewer, PID: 27809
java.lang.IllegalStateException: Could not find method loginlinkLabelonClick(View) in a parent or ancestor Context for
android:onClick attribute defined on view class
android.support.v7.widget.AppCompatTextView with id 'LoginlinkLabel'
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.resolveMethod(AppCompatViewInflater.java:423)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:380)
at android.view.View.performClick(View.java:6291)
at android.view.View$PerformClick.run(View.java:24931)
at android.os.Handler.handleCallback(Handler.java:808)
at android.os.Handler.dispatchMessage(Handler.java:101)
at android.os.Looper.loop(Looper.java:166)
at android.app.ActivityThread.main(ActivityThread.java:7425)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
But as soon as I tap the textview the application crashes and I can't seem to find what's wrong.
I'm new to Java, kotlin and Android studio.
I had a previous experience with visual studio and c# and Java / kotlin feels a bit strange
Now I'm really trying to figure out how to open urls, but I'm having trouble getting it to work
Usually when you have a click method in the xml, the argument for the method in kotlin is a view instance, see more here. So your method should look like this:
fun loginlinkLabelonClick(view:View)
{
}
I'm trying to make a mini mobile wallet which stores users' details on firebase. I'm getting the error
Attempt to invoke virtual method 'void
android.widget.TextView.setText(int)' on a null object reference
while using the setText() method to show user's balance. I've referred to many other similar questions on stackoverflow, but nothing helped me out.
Here are code files I think I have problem with.
The below code if for a fragment (wallet_info.xml)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".PassBook">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_marginTop="250dp"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="25dp"
android:id="#+id/walletText"
android:text="Wallet Balance"/>
<TextView
android:layout_margin="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="40dp"
android:layout_below="#id/walletText"
android:id="#+id/balanceText"/>
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/balanceText"
android:layout_centerHorizontal="true"
android:layout_marginTop="32dp"
android:text="Request Balance"
android:onClick="onRequest"/>
</RelativeLayout>
The android:onClick="onRequest" shows a red underline asking me to create a public method even though I've created the method in the class on which the fragment is attached.
The below code is for home.java (a class on which wallet_info.xml fragment is attached.) I'm pasting the part where I'm getting the error.
public void onRequest(View view){
tv = (TextView)findViewById(R.id.balanceText);
wallet.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
wallet_info u = dataSnapshot.child(m).getValue(wallet_info.class);
tv.setText(u.getBalance());
//tv.setText(u.getBalance());
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
The line tv.setText(u.getBalance()); throws the mentioned error.
Thank you in advance.
This is because you can't use the following attribute:
android:onClick="onRequest"
inside a layout for a Fragment. It's only work for an Activity. Hence, you need to bind the balanceText view and create the View.onClickListener for button2 button.
Though questions like this on stackoverflow didn't have the answer I needed, I came up with the solution. I don't know why it shows a NULL POINTER EXCEPTION even when I created an object of TextView. The error got solved by changing the data type of parameter in setText() to string.
The problem got resolved after changing the code as follows.
wallet_info u = dataSnapshot.child(m).getValue(wallet_info.class);
tv.setText(u.getBalance());
The above lines of code were changed to -
wallet_info u = dataSnapshot.child(m).getValue(wallet_info.class);
g = String.valueOf(u.getBalance());
tv.setText(g);
This solved my problem.
I am new to android. And I am trying to create an app where i have three imagebuttons on top in a horizontal line and fragment in below portion which can change with click of button (same like tinder android app). I have tried using two different fragments, one with three image buttons and other the below one). Then I also tried using gridview for images and then fragment in the below portion. I have also tried simply using images and dynamically changing fragments. I have got different errors resulting in crashes. What I want to know is how can I achieve my objective in most efficient way?
EDIT : Codes are following when I am using just images without gridview or fragments for imagebuttons.
package com.psycho.ayush.sahanubhooti_20;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;
import android.view.View;
import android.widget.ImageButton;
import android.widget.Toast;
public class MainActivity extends FragmentActivity {
ImageButton ngosButton, profileButtton, donateButton;
NGOsFragment ngosFragment;
ProfileFragment profileFragment;
DonateFragment donateFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ngosButton = (ImageButton)findViewById(R.id.ngoButton);
profileButtton = (ImageButton)findViewById(R.id.profileButton);
donateButton = (ImageButton)findViewById(R.id.donateButton);
ngosButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FragmentTransaction fragTrans = getSupportFragmentManager().beginTransaction();
fragTrans.add(R.id.fragment_container, ngosFragment);
fragTrans.addToBackStack(null);
fragTrans.commit();
}
});
}
}
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:id="#+id/fragment_container"
tools:context="com.psycho.ayush.sahanubhooti_20.MainActivity">
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/ngoButton"
android:src="#drawable/ngo"
android:background="#android:color/transparent" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/profileButton"
android:layout_gravity="center_horizontal|top"
android:src="#drawable/profile"
android:background="#android:color/transparent" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/donateButton"
android:layout_gravity="right|top"
android:src="#drawable/donate"
android:background="#android:color/transparent" />
</FrameLayout>
Rest I have three fragments(NGOsFragment, DonateFragment and ProfileFragment), which I have not changed. I have not added onclicklistener for rest of button in here.
07-25 21:18:09.111 23385-23407/com.psycho.ayush.sahanubhooti_20 I/OpenGLRenderer: Initialized EGL, version 1.4
07-25 21:18:09.111 23385-23407/com.psycho.ayush.sahanubhooti_20 W/OpenGLRenderer: Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without...
07-25 21:18:18.321 23385-23385/com.psycho.ayush.sahanubhooti_20 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.psycho.ayush.sahanubhooti_20, PID: 23385
java.lang.NullPointerException: Attempt to write to field 'android.support.v4.app.FragmentManagerImpl android.support.v4.app.Fragment.mFragmentManager' on a null object reference
at android.support.v4.app.BackStackRecord.doAddOp(BackStackRecord.java:418)
at android.support.v4.app.BackStackRecord.add(BackStackRecord.java:408)
at com.psycho.ayush.sahanubhooti_20.MainActivity$1.onClick(MainActivity.java:30)
at android.view.View.performClick(View.java:4756)
at android.view.View$PerformClick.run(View.java:19761)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5253)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
set on click listener on all the buttons and set the below code to set the different fragments on the frame layout. The frame layout id is the resource id of the frame layout you set in the activity and Fragment class is the fragment you created to be called on the click of the image buttons.
getSupportFragmentManager().beginTransaction().replace(R.id.frame layout id, Fragment class name).commit()
Using NavigationView from the newly released Android support design library, if a navigation header layout includes an onClick (in the xml), onClick event crashes app. OnClick can be added programmatically via view.onClickListener (instead of xml), and then clicking works fine. But for some reason, whenever xml onClick is used, there is an error.
Here's my main layout:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/mainActivityLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<RelativeLayout
android:id="#+id/mainContentFrame"
android:layout_width="match_parent"
android:layout_height="match_parent">
...
</RelativeLayout>
<android.support.design.widget.NavigationView
android:id="#+id/drawerNavView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/drawer_header"
app:menu="#menu/drawer_menu">
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
In my activity, my menu item clicks (added with navView.setNavigationItemSelectedListener()) work fine. The problem is when the header is clicked:
drawer_header.xml:
...
<View
android:id="#+id/testButton"
android:layout_width="match_parent"
android:layout_height="60dp"
android:onClick="testButtonClick"/>
...
Produces the following error:
java.lang.IllegalStateException: Could not find a method testButtonClick(View)
in the activity class android.view.ContextThemeWrapper for onClick handler
on view class android.view.View with id 'testButton'
UPDATE
NavigationView can use standard Menu resource files, but there is a similar problem if using onClick from the menu XML resource. According to the Menu Resource reference, the android:onClick attribute overrides the normal callbacks. This usually works fine, but with menu items in NavigationView, it doesn't. Instead, it crashes with this error:
java.lang.RuntimeException: Unable to start activity ComponentInfo{...}:
android.view.InflateException: Binary XML file line #34:
Error inflating class android.support.design.widget.NavigationView
The error goes away when I remove the XML onClick.
UPDATE
I tested xml onClick using the "official" demo project for the Android Design Library. Same results: adding onClick (in xml) to a NavigationView's menu or header causes the app the crash. So this appears to be a bug with NavigationView.
RESOLVED IN v23.1
Google released a fix for these XML onClick errors in Support Library v23.1.
Confirmed, this is a bug in the support library.
Apparently it's related to ContextThemeWrapper, and according to this bug report, the problem exists in Support Library 22.1.
So, the short answer is:
Don't use XML onClick with NavigationView (or some other components like EditText), until it's fixed.
Workaround:
Set click listeners in code. For NavigationView, use setNavigationItemSelectedListener().
UPDATE: This bug has ben fixed
You can now use XML onClick in Support Library 23.1 (bug report). I've verified it works in my app. But there seems to be other (newer) XML issues with NavView in v23.1 (see below), even though this particular onClick error is now fixed.
For completeness:
There appears to be another (related?) bug when inflating NavigationView header via XML. Using XML app:headerLayout produces errors with 23.1, even though XML onClick now works. Because of this inflation issue, you'll need to use NavigationView.inflateHeaderView() method in code. This new method was added in 23.1 and, apparently, the previous XML inflate is now broken (or maybe they deprecated app:headerLayout without telling anyone?). More info detailed here.
Hi: my solution is remove
app:headerLayout="#layout/drawer_header"
from your NavigationView layout as below:
<android.support.design.widget.NavigationView
android:id="#+id/drawerNavView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:menu="#menu/drawer_menu">
</android.support.design.widget.NavigationView>
And then use below in your activity or view controller
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
View headerView= navigationView.inflateHeaderView(R.layout.nav_header);
TextView tvName = (TextView) headerView.findViewById(R.id.id_nav_header_uname);
tvName.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
L.d("=======tv click=====");
}
});
this works for me.
You may write your method in code without mentioning it in XML. In code you just use the code
public void methodName()
{
//
}
View v = findViewById(R.id.view_id);
v.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
methodName();
}
});
NavigationView has an OnNavigationItemSelectedListener for the Menu Items.
e.g.
navigationView.setNavigationItemSelectedListener(new SelectedNavigationItemListener());
private class SelectedNavigationItemListener implements NavigationView.OnNavigationItemSelectedListener {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
switch (menuItem.getItemId()){
case id1:
break;
}
Log.d("MENU ITEM", menuItem.getTitle().toString());
return false;
}
}
For the Header you can do something like this e.g
navigationView = (NavigationView) findViewById(R.id.navigation_view);
View header = navigationView.inflateHeaderView(R.layout.drawer_header);
RelativeLayout drawerHeader = (RelativeLayout) header.findViewById(R.id.drawerHeader);
drawerHeader.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("CLICKED HEADER", "Header Clicked");
}
});
Reference for my HeaderLayout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawerHeader"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="12dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/app_name"
android:textSize="16sp" />
I have to develop an android application.
I have created one layout file that uses another layout file using the include tag.
<include
android:id="#+id/footer"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_alignParentBottom="true"
layout="#layout/footer_tabs" />
<include
android:id="#+id/footer1"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_alignParentBottom="true"
layout="#layout/footertabs" />
I would like to show the included layout when a response is null, otherwise I would like to hide the layout and show the other. Here is what I have so far:
footertabs = (RelativeLayout) findViewById(R.id.footertab);
footer_tabs = (RelativeLayout) findViewById(R.id.footer_tab);
if (Constants.response==null) {
footertabs.setVisibility(View.VISIBLE);
footer_tabs.setVisibility(View.GONE);
}
else
{
footertabs.setVisibility(View.GONE);
footer_tabs.setVisibility(View.VISIBLE);
}
But I'm getting the following error:
07-15 17:19:09.893: E/AndroidRuntime(15143): Caused by: java.lang.NullPointerException
07-15 17:19:09.893: E/AndroidRuntime(15143): at com.example.androidbestinuk.HomePage.onCreate(HomePage.java:56)
Please help me debug this error.
you should change
footertabs = (RelativeLayout) findViewById(R.id.footertab);
footer_tabs = (RelativeLayout) findViewById(R.id.footer_tab);
with
footertabs = (RelativeLayout) findViewById(R.id.footer);
footer_tabs = (RelativeLayout) findViewById(R.id.footer1);
Well it appears to me that you're using the wrong id's. You're getting a null pointer somewhere (I'm not sure where because there are no line numbers), but I see in your xml you have id's, footer and footer1, but in your code you are trying to find elements with id's footertab, and footer_tab. You should make these id's match.
Using ViewBinding and Kotlin, it can be achieved this way
binding.yourInclude.root.visibility = View.GONE
For specific views inside <include> tag use code below
binding.yourInclude.textView.visibility = View.GONE