I have created HideImages() function as shown below. The problem is, that running this code causes NullPointerExcpection. When I comment out the setVisibility lines, it works fine. What am I doing wrong?
public class MainActivity extends Activity implements SurfaceHolder.Callback {
ImageView img_w0, img_w1, img_w2;
public void onCreate(Bundle savedInstanceState) {
ImageView img_w0 = (ImageView)findViewById(R.id.img0);
ImageView img_w1 = (ImageView)findViewById(R.id.img1);
ImageView img_w2 = (ImageView)findViewById(R.id.img2);
HideImages();
}
public void HideImages() {
img_w0.setVisibility(View.INVISIBLE);
img_w1.setVisibility(View.INVISIBLE);
img_w2.setVisibility(View.INVISIBLE);
}
}
Make all the references of ImageView as Global as
public class MainActivity extends Activity implements SurfaceHolder.Callback {
ImageView img_w0, img_w1, img_w2;
public void onCreate(Bundle savedInstanceState) {
img_w0 = (ImageView)findViewById(R.id.img0);
img_w1 = (ImageView)findViewById(R.id.img1);
img_w2 = (ImageView)findViewById(R.id.img2);
HideImages();
}
public void HideImages() {
img_w0.setVisibility(View.INVISIBLE);
img_w1.setVisibility(View.INVISIBLE);
img_w2.setVisibility(View.INVISIBLE);
}
}
I think this may case the problem because you had already initialize ImageView above the onCreate() method the why you declare here,
img_w0 = (ImageView)findViewById(R.id.img0);
img_w1 = (ImageView)findViewById(R.id.img1);
img_w2 = (ImageView)findViewById(R.id.img2);
The problems is here. You're already declared the ImageView objects as globally. And, again you're declaring internally in onCreate()
So, just remove the declaration inside of onCreate() and run. Like below -
public void onCreate(Bundle savedInstanceState) {
img_w0 = (ImageView)findViewById(R.id.img0);
img_w1 = (ImageView)findViewById(R.id.img1);
img_w2 = (ImageView)findViewById(R.id.img2);
}
Related
public class LoginActivity extends AppCompatActivity {
#BindViews(value = {R.id.logo, R.id.first, R.id.second, R.id.last})
protected List<ImageView> sharedElements;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
ButterKnife.bind(this);
#BindViews({R.id.pager)
#BindViews(R.id.scrolling_background)
final AnimatedViewPager pager = ButterKnife.findById(this, R.id.pager);
final ImageView background = ButterKnife.findById(this, R.id.scrolling_background);
int[] screenSize = screenSize();
for (ImageView element : sharedElements) {
#ColorRes int color = element.getId() != R.id.logo ? R.color.white_transparent : R.color.color_logo_log_in;
DrawableCompat.setTint(element.getDrawable(), ContextCompat.getColor(this, color));
}
authfragment
{
public abstract class AuthFragment extends Fragment {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
protected Callback callback;
#BindView(R.id.caption)
protected VerticalTextView caption;
#BindView(R.id.root)
protected ViewGroup parent;
protected boolean lock;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View root = inflater.inflate(authLayout(), container, false);
ButterKnife.bind(this, root);
KeyboardVisibilityEvent.setEventListener(getActivity(), isOpen -> {
callback.scale(isOpen);
if (!isOpen) {
clearFocus();
}
});
return root;
}
public void setCallback(#NonNull Callback callback) {
this.callback = callback;
}
#LayoutRes
public abstract int authLayout();
public abstract void fold();
public abstract void clearFocus();
#OnClick(R.id.root)
public void unfold() {
if (!lock) {
caption.setVerticalText(false);
caption.requestLayout();
Rotate transition = new Rotate();
transition.setStartAngle(-90f);
transition.setEndAngle(0f);
transition.addTarget(caption);
TransitionSet set = new TransitionSet();
set.setDuration(getResources().getInteger(R.integer.duration));
ChangeBounds changeBounds = new ChangeBounds();
set.addTransition(changeBounds);
set.addTransition(transition);
TextSizeTransition sizeTransition = new TextSizeTransition();
sizeTransition.addTarget(caption);
set.addTransition(sizeTransition);
set.setOrdering(TransitionSet.ORDERING_TOGETHER);
caption.post(() -> {
TransitionManager.beginDelayedTransition(parent, set);
}
pls help me fix this error with butterknife . findbyid isnt also not available not able to use bindview pls help out with documentation or your code. so thats the authFragment now after some changes as suggested by GermliShx these error came maybe it my implementation error so pls help me out. this is the login page with some animation idk y butterknife is creating problem her . i tried solving it but no luck this error is due to wrong implementation of butter knife so pls hel me out
First remove this:
#BindViews({R.id.pager)
#BindViews(R.id.scrolling_background)
...
final AnimatedViewPager pager = ButterKnife.findById(this, R.id.pager);
final ImageView background = ButterKnife.findById(this, R.id.scrolling_background);
Second add this:
public class LoginActivity extends AppCompatActivity {
...
//binding is declared outside OnCreate / any other function
//your case
#BindView(R.id.pager)
AnimatedViewPager pager;
#BindView(R.id.scrolling_background)
ImageView background ;
..
//then in code just use declared pager and background when needed
#Override
protected void onCreate(Bundle savedInstanceState) {
background .setColorFilter (R.color.black); //example
}
Should work, but I am not sure what AnimatedViewPager is.
It also may show Resource IDs will be non-final in Android Gradle Plugin version 7.0, avoid using them as annotation attributes warning, but you can just suppress it.
Try and reply how is it going.
I have done I game in which I want to call on a method I have in a view from another view. I figured I would somehow have to send the "first view" into the "second view" through the my MainActivity in order for the second view to be able to call on the first view methods. However, I couldn't come up with any way of sending in the first view to the second view through my MainAcitivity, so I decided to change tactics. I now tried to have a function in my MainActivity to handle the interection between the views, but once again I was not able to call on the method from the second View.
Therefore my question is how do you send a view into another view through an Activity, or If that's not possible how do you call on an activity method through a view?
Here is the code (I added some comments to better show the problem I'm having):
public class MainActivity extends AppCompatActivity {
private FishView gameView;
private SmallBall smallBall ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RelativeLayout screen = findViewById(R.id.gameScreen);
gameView = new FishView(this);
smallBall = new SmallBall(this);
screen.addView(gameView); // first view
screen.addView(smallBall); //second view
}
//this is the method I want to reach through the View
public void handleAvoidedBall(){
gameView.avoidedBall();
}
}
public class SmallBall extends View {
private final Bitmap sodaCan;
private final static long smallBallPeriod = 60;
private final Handler handler = new Handler();
public SmallBall(Context context) {
super(context);
Paint smallBall = new Paint();
smallBall.setColor(Color.GRAY);
smallBall.setAntiAlias(false);
resetBall();
sodaCan = BitmapFactory.decodeResource(getResources(),R.drawable.sodacan);
Timer movementTimer = new Timer();
movementTimer.scheduleAtFixedRate(smallBallTask, 0, smallBallPeriod);
}
private final TimerTask smallBallTask = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
#Override
public void run() {
invalidate();
if (isBallLanded()){
//Here I want to call on a handleAvoidedBall() in MainActivity
//OR simply have gameView here if possible
// gameView.avoidedBall();
//OR
//SomeMainAcitvityObject.handleAvoidedBall();
}
}
});
}
};
#Override
protected void onDraw(Canvas canvas) {
..... //Do stuff}
}
So as I hopefully have explained somewhat decent now, I'm wondering how to either send gameView into the SmallBall view OR how to call on handleAvoidedBall() in MainActivity from the SmallBall view?
Thank you for your time and hope you have a wonderful day!
Your best option would be to define a listener that you would set on the SmallBallView.
Define the listener:
public interface BallListener {
void onAvoided(SmallBall ball);
}
And then inside your SmallBall class, you would have this method:
public void setListener(BallListener listener){
this.listener = listener;
}
And then call this in your activity, after you've instantiated the SmallBall class:
smallBall.setListener(new SmallBallListener(){
#Override
public void onAvoided(SmallBall ball){
// Do stuff here
}
})
As #LukeWaggoner mentioned, you should consider using listeners instead of making view static in your activity.
You told us, that you'd like to add more than one SmallBall views, so I figure that you don't want to write a listener's code for each of them.
It is easily doable with MainActivity implementing SmallBallListener.
Listener:
public interface SmallBallListener {
void onAvoidedBall();
}
SmallBall class:
public void setListener(SmallBallListener listener){
this.listener = listener;
}
MainActivity:
public class MainActivity extends AppCompatActivity implements SmallBallListener {
private FishView gameView;
private SmallBall smallBall ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RelativeLayout screen = findViewById(R.id.gameScreen);
gameView = new FishView(this);
screen.addView(gameView); // first view
// Add 10 small ball views
for(int i = 0; i < 10; i++) {
SmallBall ball = new SmallBall(this);
ball.setListener(this); // MainActivity is a listener here, so each ball has the same listener code
screen.addView(ball);
}
}
//this is the method I want to reach through the View
public void handleAvoidedBall() {
gameView.avoidedBall();
}
#Override
public void onAvoidedBall() { // this is the SmallBallListener method
this.handleAvoidedBall();
}
}
So whichever SmallBall view call listener.onAvoidedBall(), it will fire onAvoidedBall() method in MainActivity class.
Turns out all I had to do was to set:
private FishView gameView;
to:
public static FishView gameView;
And then simply use "MainActivity.gameView" in the SmallBall view. This gave me no additional warings either, so that was good also.
I decided to try and make my code more object oriented and avoid repetitive code in another class.
Source code for Activities :
public class EasyMode extends MainActivity {
GameActivityPVP game = new GameActivityPVP();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.game_layout_pvp);
game.initializeButtons();
}
}
public class GameActivityPVP extends MainActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.game_layout_pvp);
initializeButtons();
}
public void initializeButtons() {
button[0] = (Button) findViewById(R.id.button1);
}
}
The second the program gets to the line where I try to call a method using game.methodName(); the program crashes. No compiling errors or anything.
I am new to programming in general so please take it easy on me and I tried to simplify my code as much as possible.
Android Monitor/logcat :
W/OpenGLRenderer: Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without...
and
W/art: Before Android 4.1, method int android.support.v7.widget.ListViewCompat.lookForSelectablePosition(int, boolean) would have incorrectly overridden the package-private method in android.widget.ListView
You can use another class's method by creating object of parent class.
See below example;
Here you want to use method from 'GameActivityPVP' class. So you need to create one object in this class only.
public class GameActivityPVP extends MainActivity {
public static GameActivityPVP mGameActivity;
public GameActivityPVP getInstance(){
return mGameActivity; // assign value in onCreate() method.
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.game_layout_pvp);
mGameActivity = this; // Do not forget this, otherwise you'll get Exception here.
initializeButtons();
}
public void initializeButtons() {
button[0] = (Button) findViewById(R.id.button1);
}
}
Now use this Object in another class 'EasyMode' like this;
if(GameActivityPVP.getInstance()!=null){
GameActivityPVP.getInstance().initializeButtons();
}
Try This:
Make one Class Utils:
In Utils:
public class Utils{
private Activity context;
Button button;
public Utils(Activity context) {
this.context=context;
}
public void inititializeButton(Activity context){
button[0]= (Button) context.findViewById(R.id.button_flasher);
}
}
And in your Class use:
public class EasyMode extends MainActivity {
Utils utils;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.game_layout_pvp);
utils=new Utils(this);
utils.initializeButtons();
}
}
As already stated, you shouldn't use nested activities, they are not supposed to interact like this. If you want two activities to interact you have to do it through an intent. Regarding the duplicated code, you have few solution presented but my personal opinion is that the OOP rules are not followed. If I had to write that logic, I would create a BaseActivity to hold the common logic of the other two activities and use inheritance to extend them.
public class BaseActivity extends Activity {
protected List<Button> buttons = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.game_layout_pvp);
initializeButtons();
}
protected void initializeButtons() {
buttons.add((Button) findViewById(R.id.button1));
}
}
public class EasyMode extends BaseActivity {
// Add here logic that is used only in EasyMode activity
}
public class GameActivityPVP extends BaseActivity {
// Add here logic that is used only in GameActivityPVP activity
}
Note that in this way you don't have to override onCreate again to initialise the buttons and so on. Also, I saw that you used the same layout for both activities, but if you want to use different layouts you can do it as usual and then call initializeButtons.
I want to finish an activity by an image, and here is what I did:
there's an ImageView in the layout [activity_login.xml] .
/**
* the activity that I want to destroy
*/
public class LoginActivity extends Activity {
public static LoginActivity activityInstance;
private ImageView imgBtnBack;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
// for closing this activity by an another class
activityInstance = this;
// add event listener
imgBtnBack = (ImageView) findViewById(R.id.img_btn_back);
imgBtnBack.setOnClickListener(new LoginActivityListener());
}
#Override
protected void onDestroy() {
super.onDestroy();
}
}
/**
* the event handler of LoginActivity
*/
public class LoginActivityListener implements View.OnClickListener{
private Context context;
#Override
public void onClick(View view) {
context = view.getContext();
int id = view.getId();
switch (id) {
case R.id.img_btn_back: // close the activity by an image
LoginActivity.activityInstance.finish();
default:
break;
}
}
}
And I don't know if it was good by the way I did.
can anyone find and tell me a better way to make this work.
Add below code in your onCreate method
imgBtnBack = (ImageView) findViewById(R.id.img_btn_back);
imgBtnBack .setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
finish();
}
});
Suppose I want to create an activity that displays 12 different PNG images.
Should I create a class extending View (let say "MyView") in which I would use canvas.drawBitmap(...)?
public class MyActivity extends Activity {
private MyView myView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myView = new MyView(this);
setContentView(myView);
myView.requestFocus();
}
...
}
public class MyView extends View {
#Override
protected void onDraw(Canvas canvas) {
// do that 12 times ...
canvas.drawBitmap(...)
}
}
Or should I use 12 ImageView objects and set the bitmap in each one of it?
public class MyActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout root = new LinearLayout(this);
// do that 12 time ...
ImageView imageView = new ImageView();
Bitmap bitmap = BitmapFactory.decodeFile(...);
imageView.setImageBitmap(bitmap);
root.addView(imageView);
}
...
}
I think creating an ImageView will have more overhead.
However, it will provide more easily implemented functions