Cannot cast Int to android.view.View using Transition in Adapter class - java

Am trying to use transitions in my App but am facing this problem,
Cannot cast Int to android.view.View
Below is my code:
holder.newsRoot.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent newsIntent = new Intent(NewsAdapter.this.c, NewsDetails.class);
newsIntent.putExtra("newstitle",NewsTitle);
newsIntent.putExtra("detailednews",DetailedNews);
newsIntent.putExtra("newsdate",NewsDate);
newsIntent.putExtra("newsphoto",NewsPhoto);
ActivityOptionsCompat options= ActivityOptionsCompat.makeSceneTransitionAnimation(this,(View)news_image,"image_transit");
c.startActivity(newsIntent,options.toBundle());
}
});
Am trying to integrate it in the Adapter class, but this is the line where the problem is :
`ActivityOptionsCompat options= ActivityOptionsCompat.makeSceneTransitionAnimation(this,(View)news_image,"image_transit")`;
** problem is found on these words**
(View)news_image
My xml code of the ImageView.
<ImageView
android:id="#+id/news_image"
android:layout_width="80dp"
android:transitionName="image_transit"
android:layout_height="80dp"
android:src="#drawable/bbb"/>

PROBLEM: in android, you store the id's of your objects as int, but the int is the view id, not the view itself.
SOLUTION: in order to work with it you need to get the view use findViewById.
ImageView yourImageView = (ImageView) findViewById(R.id.news_image);
In your case you can also use it directly in the problematic method:
ActivityOptionsCompat options=
ActivityOptionsCompat.makeSceneTransitionAnimation(this,
findViewById(R.id.news_image),
"image_transit")`;
Because you placed it in the xml layout:
<ImageView android:id="#+id/news_image"

Related

Get LinearLayout reference at custom view

My question is about Android/Java.
I wanna access to other views from my custom view.
My main.xml:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/mainLinearLayout1">
<org.javaforum.input
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textEmailAddress"
required=""
android:hint="Enter your E-Mail"
oninvalid="this.setCustomValidity('SO - Please enter a correct E-Mail!!!')"/>
<org.javaforum.input
android:layout_width="wrap_content"
android:layout_height="wrap_content"
inputType="submit"/>
</LinearLayout>
So when the second "input" view is clicked, I wanna check if there exists an attribute named "required" at the first "input" view.
I tried this in my input.java:
public class input extends TextView{
public input(Context context, AttributeSet attr) {
super(context, attr, getIdentifier(context,attr));
}
#Override
public void onFinishInflate() {
setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
LinearLayout layout = (LinearLayout)findViewById(R.id.mainLinearLayout1);
View v = null;
for(int i=0; i<layout.getChildCount(); i++) {//Error
//Code
}
}
});
}
}
But I get the following error:
java.lang.NullPointerException: Attempt to invoke virtual method 'int android.widget.LinearLayout.getChildCount()' on a null object reference
I don't understand why it's null. It should be already created, right?
So how can I get an LinearLayout reference of my main.xml at my custom view correctly?
To solve the null pointer exception, you will need to search for the other widget in the parent LinearLayout. You can use View.getParent() to identify the parent. Since the view you are looking for is a sibling of the current view, you will find it in the parent.
As for determining if a certain attribute is set, I recommend that the value be captured by its view and a method provided to present that value upon request. Say the value is your "required" value then capture that value locally and provide a method, getRequiredValue(), for instance, to expose it.
You can use
LinearLayout layout = (LinearLayout) getRootView().findViewById(R.id.mainLinearLayout1);
if you only call findViewById inside custom view it only lookup the child view.
This should be called in the Activity's onCreate instead of TextView's onFinishInflate.
First give the submit button an id eg btn_submit, then in onCreate
Button btn_submit = (Button)findViewById(R.id.btn_submit);
btn_submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
LinearLayout layout = (LinearLayout)findViewById(R.id.mainLinearLayout1);
View v = null;
for(int i=0; i<layout.getChildCount(); i++) {
//Code
}
}
});

Spinner updating only on user actions

I have IconText that has image and text views inside it, both class and xml.
I then populate the Spinner inside of the MainActivity with these IconTexts, using extended BaseAdapter (IconTextAdapter) as adapter.
Now, IconText works fine (shows as it should).
Spinner however doesn't.
When I start the app, it shows the first IconText as it should.
When I open the choose dialog, everything is showing as it should.
When I select another item, the choose dialog collapses and spinner displays no IconText (ie. only "arrow down" for opening choose dialog).
I can still open the choose dialog and choose another.
I've noticed that if I exit from app (return button, not really quiting the app) and enter again that the proper IconText is shown.
I guess that the fault lies with the adapter?
I will try avoiding posting a lot of code [:
IconText.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView android:id="#+id/it_image"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="#drawable/home"/>
<TextView
android:id="#+id/it_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="20sp"
android:text="ABC"
android:textColor="#color/black_overlay"
android:textSize="20sp"
android:textStyle="bold" />
</LinearLayout>
IconText.java
public class IconText {
static LayoutInflater inflator;
public ImageView icon;
public TextView text;
public View view;
public IconText(String title, int icon_id){
Log.d("IconText", "Create");
view = inflator.inflate(R.layout.icon_text, null);
text = (TextView) view.findViewById(R.id.it_text);
icon = (ImageView) view.findViewById(R.id.it_image);
text.setText(title);
icon.setImageResource(icon_id);
}
public static void initInflator(Context context){
if(inflator != null) return;
Log.d("IconText", "Init inflator");
inflator = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
}
IconTextAdapter.java
public class IconTextAdapter extends BaseAdapter implements SpinnerAdapter{
public ArrayList<IconText> items;
public IconTextAdapter(){
super();
items = new ArrayList<>();
}
#Override
public int getCount() {
return items.size();
}
#Override
public Object getItem(int arg0) {
return items.get(arg0);
}
#Override
public long getItemId(int position) {
return items.get(position).view.getId();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
return items.get(position).view;
}
}
MainActivity, relevant code
void initFilter(){
Log.d("MainAction", "Find Filter");
filter = (Spinner) findViewById(R.id.filter);
Log.d("MainAction", "Create Adapter");
IconTextAdapter adapter = new IconTextAdapter();
Log.d("MainAction", "Create items");
for(int i=0; i<ETypes.names.length; i++){
IconText it = new IconText(ETypes.names[i], ETypes.icons[i]);
adapter.items.add(it);
}
Log.d("MainAction", "Setting adapter");
filter.setAdapter(adapter);
}
ETypes names[string] and icons[id] are static.
Inflator is initialized succesfully.
I haven't worked much in Android. If it were Java/Swing, I guess I would just call a redraw or something.
I know there are some bad practices here (all public variables, and so on). This code is still in early prototype stage, it will be fixed soon. I'm not looking for optimization, just for the solution to my problem.
Update 1:
So I saw I didn't implement getDropDownView so I did, the same code as getView (no need to post it?).
Also I made an experiment: At the end of IconText contrusctor I added
view = text
And it works just fine (showing only text).
I guess this pinpoints that the problem originates from custom view?
Update 2:
Did another experiment with IconText, setting view = icon; and it doesn't behave as it should, ie. it behaves like it's a custom view.
Doesn't really solve this specific bug, but it solves my problem.
Custom Image and Text View in Spinner Solution.
To update the list you must call
adapter.notifyDataSetChanged()
after adding new data to your adapter
Please refer to the following
https://developer.android.com/reference/android/widget/BaseAdapter.html#notifyDataSetChanged()

Calling Activity from Fragment

I have a problem with calling activity from fragment class. More:
XML of adapter's layout:
<TextView
style="#style/LiHeadLogin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:foreground="?android:attr/selectableItemBackground"
android:clickable="true"
android:onClick="openProfile"
android:id="#+id/genFrom" />
Code from main activity that calls fragment:
public void openProfile(View v) {
Fragment_Questions frau = new Fragment_Questions();
frau.openProfile(v);
}
Code from fragment class:
public void openProfile(View v) {
View row = (View) v.getParent();
TextView child2 = (TextView) row.findViewById(R.id.genFromlogin);
String child3 = child2.getText().toString();
Intent ini = getActivity().getIntent();
String c_username = ini.getStringExtra(MainActivity.KEY_USERNAME);
String c_password = ini.getStringExtra(MainActivity.KEY_PASSWORD);
Intent ini2 = new Intent(context, User.class);
ini2.putExtra(MainActivity.KEY_USERNAME, c_username);
ini2.putExtra(MainActivity.KEY_PASSWORD, c_password);
ini2.putExtra(MainActivity.KEY_USER, child3);
getActivity().startActivity(ini2);
}
Errors:
java.lang.IllegalStateException: Could not execute method for android:onClick
...
...
...
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Intent android.support.v4.app.FragmentActivity.getIntent()' on a null object reference
P.S.
1. App opens default activity
2. User calls a new activity with passing intent data
3. New activity calls fragment
The first (main) activity:
Intent intent_settings = getIntent();
String c_username = intent_settings.getStringExtra(MainActivity.KEY_USERNAME);
String c_password = intent_settings.getStringExtra(MainActivity.KEY_PASSWORD);
Intent intent_settings_1 = new Intent(this, NewFeed.class);
intent_settings_1.putExtra(MainActivity.KEY_USERNAME, c_username);
intent_settings_1.putExtra(MainActivity.KEY_PASSWORD, c_password);
intent_settings_1.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
startActivity(intent_settings_1);
Okay, and you should know that all fragments are called by viewpager with tab layout.
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
Fragment_Home tab1 = new Fragment_Home();
return tab1;
case 1:
Fragment_Questions tab2 = new Fragment_Questions();
return tab2;
default:
return null;
}
}
You can only access the activity with getActivity() between calls to onAttach() and onDetach().
Fragment_Questions itself only seems to serve the purpose to start a new activity, so you could just move all the logic to the click listener of the activity and don't use the fragment at all.
If there's more about the fragment and you're actually planning to add it to the activity sometime in the future it still seems better to have this logic separated from the fragment. You only use getActivity() and magically context in there. You could just make it static and give the activity as parameter instead.
public static void openProfile(Activity activity, View v) {
View row = (View) v.getParent();
TextView child2 = (TextView) row.findViewById(R.id.genFromlogin);
String child3 = child2.getText().toString();
Intent ini = activity.getIntent();
String c_username = ini.getStringExtra(MainActivity.KEY_USERNAME);
String c_password = ini.getStringExtra(MainActivity.KEY_PASSWORD);
Intent ini2 = new Intent(activity, User.class);
ini2.putExtra(MainActivity.KEY_USERNAME, c_username);
ini2.putExtra(MainActivity.KEY_PASSWORD, c_password);
ini2.putExtra(MainActivity.KEY_USER, child3);
activity.startActivity(ini2);
}
You should add Fragment_Questions to Activity.
For example,In Activity layout:
<LinearLayout 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=".MainActivity" >
<fragment
android:id="#+id/fragment_question"
android:name="com.example.view.Fragment_Questions"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
In Acitivity.java:
questionFragment = (Fragment_Questions) findViewById(fragment_question);
and then, you can user OnClick Event like this:
questionFragment.openProfile(v);
You are getting Null Pointer Exception because your fragment is not attached to Activity. You are just instantiating the fragment and then calling its openProfile(View v) method which is a wrong way to handle events. If you already attached fragment then get the instance of framgent using
questionFragment = (Fragment_Questions) findViewById(fragment_question);
You can read below article on how to communicate from Fragments to activity
https://developer.android.com/training/basics/fragments/communicating.html
As I have understanded the steps of the user interferance you have to replace getIntent() in the fragment with the intent that starts it which is intent_settings i think
Also make the that intent static in order to share it
And make if statment in order not to have null exception
if(theIntent.hasPutextra)
{getExtra.....}
Do you extends Fragment OR FragmetnActivity?
if you extend FragmetnActivity (as i think) then dont use getActivity()
Also add the code for the intent that started your current activity
Fragment_Questions frau = new Fragment_Questions();
frau.openProfile(v);
You just created new fragment you didnt attached it to the activity?
use FragmentManager.
if you trying to use fragment inside ViewPager use THIS guide

ClassCastException in Listview

Following code generates exception as:
java.lang.ClassCastException: java.lang.Integer cannot be cast to vro.nagainfo.vromain.model.VROUser.
listUsers is a custom listview and VROUser is a class
listUsers.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
VROUser user = (VROUser) listUsers.getItemAtPosition(position);
Intent intent = new Intent(getActivity(), ProfileViewActivity.class);
intent.putExtra("userId", user.getUserID());
getActivity().startActivity(intent);
}
});
How to fix this?
ClassCastException means you are declaring a variable of some type and assigning it to another type you have defined in a layout xml file...
Example in your xml:
<Button
android:layout_height="wrap_content"
android:id="#+id/btn1"
android:layout_width="wrap_content">
</Button>
And in your java code
ImageView img1 = (ImageView)context.findViewById(R.id.btn1);
There is no compile error. But you are face ClassCastException
Check your ListVIew. How did you declare in both xml and java code
Correct:
VROUser user = listUsers.get(position);
Here, listUsers.getItemAtPosition(position); it is giving integer value,but you have casted to VROUser.
What are you doing with this code???
VROUser user = (VROUser) listUsers.getItemAtPosition(position);
Use like this
VROUser user = listUsers.get(position);
Use it

How to make phone calls programmatically in Android?

I have the following layout defined in useful_numbers_item_fragment.xml:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:id="#+id/call_linear_layout">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/useful_nums_item_name"/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/useful_nums_item_value"/>
</LinearLayout>
<ImageButton
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="#drawable/call"
android:id="#+id/call_btn"
android:onClick="callNumber"/>
</LinearLayout>
I dynamically populate the two text views in a class called UNItemListFragment.java
in the onCreate method:
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
if (getArguments().containsKey(Constants.UNItem.GROUP_ID)) {
simpleCursorAdapter = new SimpleCursorAdapter(getActivity(), R.layout.useful_numbers_item_fragment, null,
new String[]{Constants.UNItem.NAME, Constants.UNItem.VALUE},
new int[]{R.id.useful_nums_item_name, R.id.useful_nums_item_value}, 0);
setListAdapter(simpleCursorAdapter);
getLoaderManager().initLoader(0, getArguments(), this);
}
}
For each number if i click on the button i want to make a phone call by
calling the callNumber method when the user clicks the button:
public void callNumber(View view) {
Intent callIntent = new Intent(Intent.ACTION_CALL);
TextView unItemVal = (TextView) findViewById(R.id.useful_nums_item_value);
String phoneNumber = unItemVal.getText().toString();
callIntent.setData(Uri.parse("tel:" + phoneNumber));
startActivity(callIntent);
}
It is ok when I click the first button in the list, but when I click on the other buttons
it continues calling the number defined in the first row...
Any idea how to resolve this?
The problem is that this line:
TextView unItemVal = (TextView) findViewById(R.id.useful_nums_item_value);
is executed on the activity, so the findViewById will always return the first item with that id, which is likely the first item in the list.
The best way to fix this would be to override the adapter and add a tag containing the phone number to the view. A quick way to fix this would be to tag along in the view hierarchy, like so:
public void callNumber(View view) {
if( view != null ) { // view is the button tapped
View parent = view.getParent(); // this should be the LinearLayout
if( parent instanceof LinearLayout ) {
TextView unItemVal = (TextView) ((LinearLayout)parent).findViewById(R.id.useful_nums_item_value);
if( unItemVal != null ) {
Intent callIntent = new Intent(Intent.ACTION_CALL);
String phoneNumber = unItemVal.getText().toString();
callIntent.setData(Uri.parse("tel:" + phoneNumber));
startActivity(callIntent);
}
}
}
}
This would find the parent for the button that was clicked, and then find the text-view containing the number within that ViewGroup.
Using findViewById() will return the first view in the activity or fragment with the specified id. If this is a ListView, it will correspond to the first row.
There are many ways to work around this problem. The quickest one (but certainly not the prettiest one, since it depends on the layout) would be to use findViewById() relative to the LinearLayout that contains the list item. Assuming that view is the ImageButton, it would be somthing like:
((View)view.getParent()).findViewById(R.id.useful_nums_item_value)
A more elegant solution would be to set a tag in the adapter's getView(), containing the data you need (in this case, the phone number to call).

Categories

Resources