问:
iphone app click delete crash
In my application when I press the delete row will crash. I tried to find a solution to this problem already, hope can help me solve it.

My code here:

FirstView.h

```<code>#import <UIKit/UIKit.h>
@interface FirstView : UIViewController <UITextFieldDelegate,UITableViewDataSource,UITableViewDelegate>{

IBOutlet UITableView *tableview;
IBOutlet UIDatePicker *datePicker;
IBOutlet UITextField *eventText;

NSArray *notificationArray;
NSMutableArray *Array;
   }
@property (nonatomic, retain) IBOutlet UITableView *tableview;
@property (nonatomic, retain) IBOutlet UIDatePicker *datePicker;
@property (nonatomic, retain) IBOutlet UITextField *eventText;

- (IBAction) scheduleAlarm:(id) sender;
@end
</code>```

FirstView.m

```<code>#import "FirstView.h"

    @implementation FirstView
    @synthesize datePicker, eventText,tableview;

    - (void) viewWillAppear:(BOOL)animated {
    [self.tableview reloadData];
    }

    - (IBAction) scheduleAlarm:(id) sender {
    [eventText resignFirstResponder];

    NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];

    // Get the current date
    NSDate *pickerDate = [self.datePicker date];

    // Break the date up into components
    NSDateComponents *dateComponents = [calendar components:( NSYearCalendarUnit |        NSMonthCalendarUnit |  NSDayCalendarUnit )
                                                     fromDate:pickerDate];
    NSDateComponents *timeComponents = [calendar components:( NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit )
                                                   fromDate:pickerDate];

    // Set up the fire time
    NSDateComponents *dateComps = [[NSDateComponents alloc] init];
    [dateComps setDay:[dateComponents day]];
    [dateComps setMonth:[dateComponents month]];
    [dateComps setYear:[dateComponents year]];
    [dateComps setHour:[timeComponents hour]];
    // Notification will fire in one minute
    [dateComps setMinute:[timeComponents minute]];
    [dateComps setSecond:[timeComponents second]];
    NSDate *itemDate = [calendar dateFromComponents:dateComps];
    [dateComps release];

    UILocalNotification *localNotif = [[UILocalNotification alloc] init];
    if (localNotif == nil)
        return;
    localNotif.fireDate = itemDate;
    localNotif.timeZone = [NSTimeZone defaultTimeZone];

    // Notification details
    localNotif.alertBody = [eventText text];
    // Set the action button
    localNotif.alertAction = @"View";

    localNotif.soundName = UILocalNotificationDefaultSoundName;
    localNotif.applicationIconBadgeNumber = 1;

    // Specify custom data for the notification
    NSDictionary *infoDict = [NSDictionary dictionaryWithObject:@"someValue" forKey:@"someKey"];
    localNotif.userInfo = infoDict;

    // Schedule the notification
    [[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
    [localNotif release];

    [self.tableview reloadData];

    }
    // The designated initializer.  Override if you create the controller programmatically     and want to perform customization that is not appropriate for viewDidLoad.
     /*
     - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization.
    }
    return self;
    }
    */

    // Implement viewDidLoad to do additional setup after loading the view, typically from a    nib.
- (void)viewDidLoad {
    eventText.delegate = self;
    Array = [notificationArray mutableCopy];

    [super viewDidLoad];
     }

     #pragma mark -
     #pragma mark Table view data source

      - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    // Return the number of sections.
    return 1;
      }

     - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    // Return the number of rows in the section.
    return [[[UIApplication sharedApplication] scheduledLocalNotifications] count];
      }

      // Customize the appearance of table view cells.
      - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle   reuseIdentifier:CellIdentifier] autorelease];
      }

    // Configure the cell...

    notificationArray = [[UIApplication sharedApplication] scheduledLocalNotifications];
    UILocalNotification *notif = [notificationArray objectAtIndex:indexPath.row];

    [cell.textLabel setText:notif.alertBody];
    [cell.detailTextLabel setText:[notif.fireDate description]];

    return cell;
}
     - (void)tableView:(UITableView *)tv commitEditingStyle:    (UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    // If row is deleted, remove it from the list.
    if (editingStyle == UITableViewCellEditingStyleDelete) {

    [Array removeObjectAtIndex:indexPath.row];
    [self.tableview deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];

    }
}
/*
     // Override to allow orientations other than the default portrait orientation.
    - (BOOL)shouldAutorotateToInterfaceOrientation:  (UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations.
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
     }
*/
      - (BOOL)textFieldShouldReturn:(UITextField *)theTextField {
    [eventText resignFirstResponder];
    return YES;
}
        - (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc. that aren't in use.
      }

     - (void)viewDidUnload {
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
    datePicker = nil;
        eventText = nil;
}

- (void)dealloc {
    [super dealloc];
}

@end
</code>```

the crash log here.

```<code>2011-04-12 13:27:26.860 SMS Timer[2050:207] *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-1448.89/UITableView.m:995
2011-04-12 13:27:26.863 SMS Timer[2050:207] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0.  The number of rows contained in an existing section after the update (5) must be equal to the number of rows contained in that section before the update (5), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted).'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x00dca5a9 __exceptionPreprocess + 185
    1   libobjc.A.dylib                     0x00f1e313 objc_exception_throw + 44
    2   CoreFoundation                      0x00d82ef8 +[NSException raise:format:arguments:] + 136
    3   Foundation                          0x000b53bb -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 116
    4   UIKit                               0x00338e8b -[UITableView(_UITableViewPrivate) _endCellAnimationsWithContext:] + 8420
    5   UIKit                               0x00327cf8 -[UITableView deleteRowsAtIndexPaths:withRowAnimation:] + 56
    6   SMS Timer                           0x00003414 -[FirstView tableView:commitEditingStyle:forRowAtIndexPath:] + 189
    7   UIKit                               0x00325037 -[UITableView(UITableViewInternal) animateDeletionOfRowWithCell:] + 101
    8   UIKit                               0x002ba4fd -[UIApplication sendAction:to:from:forEvent:] + 119
    9   UIKit                               0x0034a799 -[UIControl sendAction:to:forEvent:] + 67
    10  UIKit                               0x0034cc2b -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 527
    11  UIKit                               0x0034b7d8 -[UIControl touchesEnded:withEvent:] + 458
    12  UIKit                               0x002deded -[UIWindow _sendTouchesForEvent:] + 567
    13  UIKit                               0x002bfc37 -[UIApplication sendEvent:] + 447
    14  UIKit                               0x002c4f2e _UIApplicationHandleEvent + 7576
    15  GraphicsServices                    0x01722992 PurpleEventCallback + 1550
    16  CoreFoundation                      0x00dab944 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
    17  CoreFoundation                      0x00d0bcf7 __CFRunLoopDoSource1 + 215
    18  CoreFoundation                      0x00d08f83 __CFRunLoopRun + 979
    19  CoreFoundation                      0x00d08840 CFRunLoopRunSpecific + 208
    20  CoreFoundation                      0x00d08761 CFRunLoopRunInMode + 97
    21  GraphicsServices                    0x017211c4 GSEventRunModal + 217
    22  GraphicsServices                    0x01721289 GSEventRun + 115
    23  UIKit                               0x002c8c93 UIApplicationMain + 1160
    24  SMS Timer                           0x00002754 main + 102
    25  SMS Timer                           0x000026e5 start + 53
)
terminate called after throwing an instance of 'NSException'
</code>```

答:
```<code>- (void)tableView:(UITableView *)tv commitEditingStyle:    (UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    // If row is deleted, remove it from the list.
    if (editingStyle == UITableViewCellEditingStyleDelete) {

    [Array removeObjectAtIndex:indexPath.row];
    [self.tableview deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];

//TRy to set your count for this line
//[[[UIApplication sharedApplication] scheduledLocalNotifications] count];IF you are getting this proper after deleting the cell, then it won;t crash.Since you are deleting the cell but not updating the count so still it return 5 intend of 4 after deleting the data.
[self.tableView reloadData];
    }
</code>```

<p>Hope that works...Lets give hand on this </p>

Title: iphone app click delete crash

Body:
In my application when I press the delete row will crash. I tried to find a solution to this problem already, hope can help me solve it.

My code here:

FirstView.h

#import <UIKit/UIKit.h>
@interface FirstView : UIViewController <UITextFieldDelegate,UITableViewDataSource,UITableViewDelegate>{

IBOutlet UITableView *tableview;
IBOutlet UIDatePicker *datePicker;
IBOutlet UITextField *eventText;

NSArray *notificationArray;
NSMutableArray *Array;
   }
@property (nonatomic, retain) IBOutlet UITableView *tableview;
@property (nonatomic, retain) IBOutlet UIDatePicker *datePicker;
@property (nonatomic, retain) IBOutlet UITextField *eventText;

- (IBAction) scheduleAlarm:(id) sender;
@end

FirstView.m

#import "FirstView.h"

    @implementation FirstView
    @synthesize datePicker, eventText,tableview;

    - (void) viewWillAppear:(BOOL)animated {
    [self.tableview reloadData];
    }

    - (IBAction) scheduleAlarm:(id) sender {
    [eventText resignFirstResponder];

    NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];

    // Get the current date
    NSDate *pickerDate = [self.datePicker date];

    // Break the date up into components
    NSDateComponents *dateComponents = [calendar components:( NSYearCalendarUnit |        NSMonthCalendarUnit |  NSDayCalendarUnit )
                                                     fromDate:pickerDate];
    NSDateComponents *timeComponents = [calendar components:( NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit )
                                                   fromDate:pickerDate];

    // Set up the fire time
    NSDateComponents *dateComps = [[NSDateComponents alloc] init];
    [dateComps setDay:[dateComponents day]];
    [dateComps setMonth:[dateComponents month]];
    [dateComps setYear:[dateComponents year]];
    [dateComps setHour:[timeComponents hour]];
    // Notification will fire in one minute
    [dateComps setMinute:[timeComponents minute]];
    [dateComps setSecond:[timeComponents second]];
    NSDate *itemDate = [calendar dateFromComponents:dateComps];
    [dateComps release];

    UILocalNotification *localNotif = [[UILocalNotification alloc] init];
    if (localNotif == nil)
        return;
    localNotif.fireDate = itemDate;
    localNotif.timeZone = [NSTimeZone defaultTimeZone];

    // Notification details
    localNotif.alertBody = [eventText text];
    // Set the action button
    localNotif.alertAction = @"View";

    localNotif.soundName = UILocalNotificationDefaultSoundName;
    localNotif.applicationIconBadgeNumber = 1;

    // Specify custom data for the notification
    NSDictionary *infoDict = [NSDictionary dictionaryWithObject:@"someValue" forKey:@"someKey"];
    localNotif.userInfo = infoDict;

    // Schedule the notification
    [[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
    [localNotif release];

    [self.tableview reloadData];

    }
    // The designated initializer.  Override if you create the controller programmatically     and want to perform customization that is not appropriate for viewDidLoad.
     /*
     - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization.
    }
    return self;
    }
    */

    // Implement viewDidLoad to do additional setup after loading the view, typically from a    nib.
- (void)viewDidLoad {
    eventText.delegate = self;
    Array = [notificationArray mutableCopy];

    [super viewDidLoad];
     }

     #pragma mark -
     #pragma mark Table view data source

      - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    // Return the number of sections.
    return 1;
      }

     - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    // Return the number of rows in the section.
    return [[[UIApplication sharedApplication] scheduledLocalNotifications] count];
      }

      // Customize the appearance of table view cells.
      - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle   reuseIdentifier:CellIdentifier] autorelease];
      }

    // Configure the cell...

    notificationArray = [[UIApplication sharedApplication] scheduledLocalNotifications];
    UILocalNotification *notif = [notificationArray objectAtIndex:indexPath.row];

    [cell.textLabel setText:notif.alertBody];
    [cell.detailTextLabel setText:[notif.fireDate description]];

    return cell;
}
     - (void)tableView:(UITableView *)tv commitEditingStyle:    (UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    // If row is deleted, remove it from the list.
    if (editingStyle == UITableViewCellEditingStyleDelete) {

    [Array removeObjectAtIndex:indexPath.row];
    [self.tableview deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];

    }
}
/*
     // Override to allow orientations other than the default portrait orientation.
    - (BOOL)shouldAutorotateToInterfaceOrientation:  (UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations.
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
     }
*/
      - (BOOL)textFieldShouldReturn:(UITextField *)theTextField {
    [eventText resignFirstResponder];
    return YES;
}
        - (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc. that aren't in use.
      }

     - (void)viewDidUnload {
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
    datePicker = nil;
        eventText = nil;
}

- (void)dealloc {
    [super dealloc];
}

@end

the crash log here.

2011-04-12 13:27:26.860 SMS Timer[2050:207] *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-1448.89/UITableView.m:995
2011-04-12 13:27:26.863 SMS Timer[2050:207] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0.  The number of rows contained in an existing section after the update (5) must be equal to the number of rows contained in that section before the update (5), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted).'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x00dca5a9 __exceptionPreprocess + 185
    1   libobjc.A.dylib                     0x00f1e313 objc_exception_throw + 44
    2   CoreFoundation                      0x00d82ef8 +[NSException raise:format:arguments:] + 136
    3   Foundation                          0x000b53bb -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 116
    4   UIKit                               0x00338e8b -[UITableView(_UITableViewPrivate) _endCellAnimationsWithContext:] + 8420
    5   UIKit                               0x00327cf8 -[UITableView deleteRowsAtIndexPaths:withRowAnimation:] + 56
    6   SMS Timer                           0x00003414 -[FirstView tableView:commitEditingStyle:forRowAtIndexPath:] + 189
    7   UIKit                               0x00325037 -[UITableView(UITableViewInternal) animateDeletionOfRowWithCell:] + 101
    8   UIKit                               0x002ba4fd -[UIApplication sendAction:to:from:forEvent:] + 119
    9   UIKit                               0x0034a799 -[UIControl sendAction:to:forEvent:] + 67
    10  UIKit                               0x0034cc2b -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 527
    11  UIKit                               0x0034b7d8 -[UIControl touchesEnded:withEvent:] + 458
    12  UIKit                               0x002deded -[UIWindow _sendTouchesForEvent:] + 567
    13  UIKit                               0x002bfc37 -[UIApplication sendEvent:] + 447
    14  UIKit                               0x002c4f2e _UIApplicationHandleEvent + 7576
    15  GraphicsServices                    0x01722992 PurpleEventCallback + 1550
    16  CoreFoundation                      0x00dab944 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
    17  CoreFoundation                      0x00d0bcf7 __CFRunLoopDoSource1 + 215
    18  CoreFoundation                      0x00d08f83 __CFRunLoopRun + 979
    19  CoreFoundation                      0x00d08840 CFRunLoopRunSpecific + 208
    20  CoreFoundation                      0x00d08761 CFRunLoopRunInMode + 97
    21  GraphicsServices                    0x017211c4 GSEventRunModal + 217
    22  GraphicsServices                    0x01721289 GSEventRun + 115
    23  UIKit                               0x002c8c93 UIApplicationMain + 1160
    24  SMS Timer                           0x00002754 main + 102
    25  SMS Timer                           0x000026e5 start + 53
)
terminate called after throwing an instance of 'NSException'

Body:
- (void)tableView:(UITableView *)tv commitEditingStyle:    (UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    // If row is deleted, remove it from the list.
    if (editingStyle == UITableViewCellEditingStyleDelete) {

    [Array removeObjectAtIndex:indexPath.row];
    [self.tableview deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];

//TRy to set your count for this line
//[[[UIApplication sharedApplication] scheduledLocalNotifications] count];IF you are getting this proper after deleting the cell, then it won;t crash.Since you are deleting the cell but not updating the count so still it return 5 intend of 4 after deleting the data.
[self.tableView reloadData];
    }

Hope that works...Lets give hand on this


来源: stackexchange

问:
Android Studio Unable to find explicit activity class although class exists
I'm stuck with some code for school. I followed a tutorial and feel like I have 100% the same (checked multiple times). But still I get an error. Android Studio doesn't show any mistakes.

Thanks a lot for any help!

I get the following error:

```<code>   --------- beginning of crash
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.ecosense, PID: 4840
    android.content.ActivityNotFoundException: Unable to find explicit activity class {com.example.ecosense/com.example.ecosense.ResultActivity}; have you declared this activity in your AndroidManifest.xml?
        at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:2005)
        at android.app.Instrumentation.execStartActivity(Instrumentation.java:1673)
        at android.app.Activity.startActivityForResult(Activity.java:4586)
        at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:767)
        at android.app.Activity.startActivityForResult(Activity.java:4544)
        at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:754)
        at com.example.ecosense.QuestionActivity.finishGame(QuestionActivity.kt:318)
        at com.example.ecosense.QuestionActivity.access$finishGame(QuestionActivity.kt:44)
        at com.example.ecosense.QuestionActivity$onOptionsItemSelected$2.onClick(QuestionActivity.kt:375)
        at com.afollestad.materialdialogs.MaterialDialog.onClick(MaterialDialog.java:367)
        at android.view.View.performClick(View.java:6597)
        at android.view.View.performClickInternal(View.java:6574)
        at android.view.View.access$3100(View.java:778)
        at android.view.View$PerformClick.run(View.java:25885)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
</code>```

And this is my QuestionActivity class.

```<code>package com.example.ecosense

import android.app.Activity
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Bundle
import android.os.CountDownTimer
import android.support.constraint.ConstraintLayout
import android.support.design.widget.Snackbar
import android.support.design.widget.NavigationView
import android.support.v4.content.LocalBroadcastManager
import android.support.v4.view.GravityCompat
import android.support.v4.view.ViewPager
import android.support.v4.widget.DrawerLayout
import android.support.v7.app.ActionBarDrawerToggle
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.GridLayoutManager
import android.support.v7.widget.RecyclerView
import android.text.TextUtils
import android.view.Gravity
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.Button
import android.widget.TextView
import com.example.ecosense.Adapter.GridAnswerAdapter
import com.example.ecosense.Adapter.MyFragmentAdapter
import com.example.ecosense.Adapter.QuestionListHelperAdapter
import com.github.javiersantos.materialstyleddialogs.MaterialStyledDialog
import com.example.ecosense.Common.Common
import com.example.ecosense.Common.SpacesItemDecoration
import com.example.ecosense.DBHelper.DBHelper
import com.example.ecosense.Model.CurrentQuestion
import com.google.gson.Gson
import kotlinx.android.synthetic.main.activity_question.*
import kotlinx.android.synthetic.main.app_bar_question.*
import kotlinx.android.synthetic.main.content_question.*
import org.w3c.dom.Text
import java.lang.StringBuilder
import java.util.concurrent.TimeUnit

class QuestionActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {

    val CODE_GET_RESULT = 9999

    lateinit var countDownTimer: CountDownTimer

    var time_play = Common.TOTAL_TIME

    var isAnswerModeView = false

    lateinit var adapter: GridAnswerAdapter

    lateinit var questionHelperAdapter: QuestionListHelperAdapter

    lateinit var txt_wrong_answer: TextView

    internal var goToQuestionNum: BroadcastReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            if (intent!!.action!!.toString() == Common.KEY_GO_TO_QUESTION) {
                val question = intent!!.getIntExtra(Common.KEY_GO_TO_QUESTION, -1)
                if (question != -1)
                    view_pager.currentItem = question

                drawer_layout.closeDrawer(Gravity.LEFT)
            }
        }

    }

    override fun onDestroy() {
        LocalBroadcastManager.getInstance(this).unregisterReceiver(goToQuestionNum)
        if (countDownTimer != null)
            countDownTimer!!.cancel()
        if (Common.fragmentList != null)
            Common.fragmentList.clear()
        if (Common.answerSheetList != null)
            Common.answerSheetList.clear()
        super.onDestroy()
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_question)
        setSupportActionBar(toolbar)

        LocalBroadcastManager.getInstance(this)
            .registerReceiver(goToQuestionNum, IntentFilter(Common.KEY_GO_TO_QUESTION))

        val toggle = ActionBarDrawerToggle(
            this, drawer_layout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close
        )
        drawer_layout.addDrawerListener(toggle)
        toggle.syncState()

        nav_view.setNavigationItemSelectedListener(this)

        val recycler_helper_answer_sheet =
            nav_view.getHeaderView(0).findViewById<View>(R.id.answer_sheet) as RecyclerView
        recycler_helper_answer_sheet.layoutManager = GridLayoutManager(this, 3)
        recycler_helper_answer_sheet.setHasFixedSize(true)
        recycler_helper_answer_sheet.addItemDecoration(SpacesItemDecoration(2))

        val btn_done = nav_view.getHeaderView(0).findViewById<View>(R.id.btn_done) as Button
        btn_done.setOnClickListener {
            if (!isAnswerModeView)
            {
                MaterialStyledDialog.Builder(this@QuestionActivity)
                    .setTitle("Finish?")
                    .setDescription("Do you really want to finish?")
                    .setIcon(R.drawable.ic_mood_white_24dp)
                    .setNegativeText("No")
                    .onNegative { dialog, which -> dialog.dismiss() }
                    .setPositiveText("Yes")
                    .onPositive { dialog, which -> finishGame()
                     drawer_layout.closeDrawer(Gravity.LEFT)}
                    .show()

            }
            else {
                finishGame()

            }
        }

        //Get Question base on Category
        genQuestion()

        if (Common.questionList.size > 0) {
            //Show Timer, Right Answer text view
            txt_timer.visibility = View.VISIBLE
            txt_right_answer.visibility = View.VISIBLE

            countTimer()

            //Gen item for grid_answer
            genItems()
            grid_answer.setHasFixedSize(true)
            if (Common.questionList.size > 0)
                grid_answer.layoutManager = GridLayoutManager(
                    this,
                    if (Common.questionList.size > 5) Common.questionList.size / 2 else Common.questionList.size
                )
            adapter = GridAnswerAdapter(this, Common.answerSheetList)

            grid_answer.adapter = adapter

            //Gen fragment list
            genFragmentList()

            val fragmentAdapter = MyFragmentAdapter(supportFragmentManager, this, Common.fragmentList)
            view_pager.offscreenPageLimit = Common.questionList.size
            view_pager.adapter = fragmentAdapter // Bind question to View Pager

            sliding_tabs.setupWithViewPager(view_pager)

            //Event
            view_pager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {

                val SCROLLING_RIGHT = 0
                val SCROLLING_LEFT = 1
                val SCROLLING_UNDETERMINED = 2

                var currentScrollDirection = SCROLLING_UNDETERMINED

                private val isScrollDirectionUndetermined: Boolean
                    get() = currentScrollDirection == SCROLLING_UNDETERMINED
                private val isScrollDirectionRight: Boolean
                    get() = currentScrollDirection == SCROLLING_RIGHT
                private val isScrollDirectionLeft: Boolean
                    get() = currentScrollDirection == SCROLLING_LEFT

                private fun setScrollingDirection(positionOffset: Float) {
                    if (1 - positionOffset >= 0.5)
                        this.currentScrollDirection = SCROLLING_RIGHT
                    else if (1 - positionOffset <= 0.5)
                        this.currentScrollDirection = SCROLLING_LEFT

                }

                override fun onPageScrollStateChanged(p0: Int) {
                    if (p0 == ViewPager.SCROLL_STATE_IDLE)
                        this.currentScrollDirection = SCROLLING_UNDETERMINED
                }

                override fun onPageScrolled(p0: Int, p1: Float, p2: Int) {
                    if (isScrollDirectionUndetermined)
                        setScrollingDirection(p1)
                }

                override fun onPageSelected(p0: Int) {

                    val questionFragment: QuestionFragment
                    var position = 0
                    if (p0 > 0) {
                        if (isScrollDirectionRight) {
                            questionFragment = Common.fragmentList[p0 - 1]
                            position = p0 - 1
                        } else if (isScrollDirectionLeft) {
                            questionFragment = Common.fragmentList[p0 + 1]
                            position = p0 + 1
                        } else {
                            questionFragment = Common.fragmentList[p0]
                        }
                    } else {
                        questionFragment = Common.fragmentList[0]
                        position = 0
                    }

                    if (Common.answerSheetList[position].type == Common.ANSWER_TYPE.NO_ANSWER) {
                        // If you want to show correct answer, enable it
                        val question_state = questionFragment.selectedAnswer()
                        Common.answerSheetList[position] = question_state
                        adapter.notifyDataSetChanged()
                        questionHelperAdapter.notifyDataSetChanged()

                        countCorrectAnswer()

                        txt_right_answer.text = ("${Common.right_answer_count} / ${Common.questionList.size}")
                        txt_wrong_answer.text = "${Common.wrong_answer_count}"

                        if (question_state.type != Common.ANSWER_TYPE.NO_ANSWER) {
                            questionFragment.showCorrectAnswer()
                            questionFragment.disableAnswer()
                        }
                    }
                }

            })

            txt_right_answer.text = "${Common.right_answer_count}/${Common.questionList.size}"
            questionHelperAdapter = QuestionListHelperAdapter(this, Common.answerSheetList)
            recycler_helper_answer_sheet.adapter = questionHelperAdapter
        }
    }

    private fun countCorrectAnswer() {
        Common.right_answer_count = 0 // Reset
        Common.wrong_answer_count = 0

        for (item in Common.answerSheetList)
            if (item.type == Common.ANSWER_TYPE.RIGHT_ANSWER)
                Common.right_answer_count++
            else if (item.type == Common.ANSWER_TYPE.WRONG_ANSWER)
                Common.wrong_answer_count++
    }

    private fun genFragmentList() {
        for (i in Common.questionList.indices) {
            val bundle = Bundle()
            bundle.putInt("index", i)
            val fragment = QuestionFragment()
            fragment.arguments = bundle

            Common.fragmentList.add(fragment)
        }
    }

    private fun genItems() {
        for (i in Common.questionList.indices)
            Common.answerSheetList.add(CurrentQuestion(i, Common.ANSWER_TYPE.NO_ANSWER)) // No answer for all questions
    }

    private fun countTimer() {
        countDownTimer = object : CountDownTimer(Common.TOTAL_TIME.toLong(), 1000) {
            override fun onFinish() {
                finishGame()
            }

            override fun onTick(interval: Long) {
                txt_timer.text = (java.lang.String.format(
                    "%02d:%02d",
                    TimeUnit.MILLISECONDS.toMinutes(interval),
                    TimeUnit.MILLISECONDS.toSeconds(interval) - TimeUnit.MINUTES.toSeconds(
                        TimeUnit.MILLISECONDS.toMinutes(
                            interval
                        )
                    )
                ))
                time_play -= 1000
            }

        }.start()
    }

    private fun finishGame() {
        val position = view_pager.currentItem
        val questionFragment = Common.fragmentList[position]

        val question_state = questionFragment.selectedAnswer()
        Common.answerSheetList[position] = question_state
        adapter.notifyDataSetChanged()
        questionHelperAdapter.notifyDataSetChanged()

        countCorrectAnswer()

        txt_right_answer.text = ("${Common.right_answer_count} / ${Common.questionList.size}")
        txt_wrong_answer.text = "${Common.wrong_answer_count}"

        if (question_state.type != Common.ANSWER_TYPE.NO_ANSWER) {
            questionFragment.showCorrectAnswer()
            questionFragment.disableAnswer()
        }

        val intent = Intent(this@QuestionActivity, ResultActivity::class.java)
        Common.timer = Common.TOTAL_TIME - time_play
        Common.no_answer_count = Common.questionList.size - (Common.right_answer_count + Common.wrong_answer_count)
        Common.data_question = StringBuilder(Gson().toJson(Common.answerSheetList))

        startActivityForResult(intent, CODE_GET_RESULT)

    }

    private fun genQuestion() {
        Common.questionList = DBHelper.getInstance(this)
            .getQuestionByCategory(Common.selectedCategory!!.id)

        if (Common.questionList.size == 0) {
            MaterialStyledDialog.Builder(this)
                .setTitle("Oppps!")
                .setIcon(R.drawable.ic_sentiment_very_dissatisfied_black_24dp)
                .setDescription("We don't have any question in this ${Common.selectedCategory!!.name} category")
                .setPositiveText("OK")
                .onPositive { dialog, which ->
                    dialog.dismiss()
                    finish()
                }.show()
        }
    }

    override fun onBackPressed() {
        val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
        if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
            drawerLayout.closeDrawer(GravityCompat.START)
        } else {
            this.finish() // Close this activity when click on back button
            super.onBackPressed()
        }
    }

    override fun onPrepareOptionsMenu(menu: Menu?): Boolean {
        val item = menu!!.findItem(R.id.menu_wrong_answer)
        val layout = item.actionView as ConstraintLayout
        txt_wrong_answer = layout.findViewById(R.id.txt_wrong_answer) as TextView
        txt_wrong_answer.text = 0.toString()
        return true
    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        // Inflate the menu; this adds items to the action bar if it is present.
        menuInflater.inflate(R.menu.question, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.menu_done -> {
                if (!isAnswerModeView) {
                    MaterialStyledDialog.Builder(this@QuestionActivity)
                        .setTitle("Finish?")
                        .setDescription("Do you really want to finish?")
                        .setIcon(R.drawable.ic_mood_white_24dp)
                        .setNegativeText("No")
                        .onNegative { dialog, which -> dialog.dismiss() }
                        .setPositiveText("Yes")
                        .onPositive { dialog, which ->
                            finishGame()
                            drawer_layout.closeDrawer(Gravity.LEFT)
                        }.show()

                } else {
                    finishGame()
                }
            }
        }
        return true

    }

    override fun onNavigationItemSelected(item: MenuItem): Boolean {
        // Handle navigation view item clicks here.
        when (item.itemId) {
            R.id.nav_home -> {
                // Handle the camera action
            }
            R.id.nav_gallery -> {

            }
            R.id.nav_slideshow -> {

            }
            R.id.nav_tools -> {

            }
            R.id.nav_share -> {

            }
            R.id.nav_send -> {

            }
        }
        val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
        drawerLayout.closeDrawer(GravityCompat.START)
        return true
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == CODE_GET_RESULT)
        {
            if (resultCode == Activity.RESULT_OK)
            {
                val action = data!!.getStringExtra("action")
                if (action == null || TextUtils.isEmpty(action))
                {
                    val questionIndex = data.getIntExtra(Common.KEY_BACK_FROM_RESULT, -1)
                    view_pager.currentItem = questionIndex

                    isAnswerModeView = true
                    countDownTimer!!.cancel()

                    txt_wrong_answer.visibility = View.GONE
                    txt_right_answer.visibility = View.GONE
                    txt_timer.visibility = View.GONE
                }
                else
                {
                    if (action.equals("doquizagain"))
                        {
                            view_pager.currentItem = 0
                            isAnswerModeView = false

                        txt_wrong_answer.visibility = View.VISIBLE
                        txt_right_answer.visibility = View.VISIBLE
                        txt_timer.visibility = View.VISIBLE

                        for (i in Common.fragmentList.indices) {
                            Common.fragmentList[i].resetQuestion()
                        }

                        for (i in Common.answerSheetList.indices)
                            Common.answerSheetList[i].type = Common.ANSWER_TYPE.NO_ANSWER

                        adapter.notifyDataSetChanged()
                        questionHelperAdapter.notifyDataSetChanged()

                        countTimer()

                    } else if (action.equals("viewanswer"))
                    {
                        view_pager.currentItem = 0
                        isAnswerModeView = true
                        countDownTimer!!.cancel()

                        txt_wrong_answer.visibility = View.GONE
                        txt_right_answer.visibility = View.GONE
                        txt_timer.visibility = View.GONE

                        for (i in Common.fragmentList.indices)
                        {
                            Common.fragmentList[i].showCorrectAnswer()
                            Common.fragmentList[i].disableAnswer()
                        }
                        }
                    }
                }
            }
    }
}
</code>```

My ResultActivity class:

```<code>package com.example.ecosense

import android.app.Activity
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.support.v4.content.LocalBroadcastManager
import android.support.v7.widget.GridLayoutManager
import android.view.Gravity
import android.view.Menu
import android.view.MenuItem
import com.example.ecosense.Adapter.ResultGridAdapter
import com.example.ecosense.Common.Common
import com.example.ecosense.Common.SpacesItemDecoration
import com.github.javiersantos.materialstyleddialogs.MaterialStyledDialog
import kotlinx.android.synthetic.main.activity_question.*
import kotlinx.android.synthetic.main.activity_result.*
import kotlinx.android.synthetic.main.activity_result.txt_right_answer
import kotlinx.android.synthetic.main.content_question.*
import java.util.concurrent.TimeUnit

class ResultActivity : AppCompatActivity() {

    internal var backToQuestion:BroadcastReceiver = object:BroadcastReceiver(){
        override fun onReceive(context: Context?, intent: Intent?) {
            if (intent!!.action!!.toString() == Common.KEY_BACK_FROM_RESULT)
            {
                val questionIndex = intent.getIntExtra(Common.KEY_BACK_FROM_RESULT,-1)
                goBackActivityWithQuestionIndex(questionIndex)
            }
        }

    }

    private fun goBackActivityWithQuestionIndex(questionIndex: Int) {
        val returnIntent = Intent()
        returnIntent.putExtra(Common.KEY_BACK_FROM_RESULT,questionIndex)
        setResult(Activity.RESULT_OK,returnIntent)
        finish()

    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.menu_result,menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem?): Boolean {
        when(item!!.itemId)
        {
            R.id.menu_do_quiz_again -> doQuizAgain()
            R.id.menu_view_answer -> viewAnswer()
            android.R.id.home -> {
                val intent = Intent(applicationContext,CategoryActivity::class.java)
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
                startActivity(intent) // Go back to category when click on back arrow in result activity
            }
        }
        return true
    }

    private fun viewAnswer() {
        val returnIntent = Intent()
        returnIntent.putExtra("action","viewanswer")
        setResult(Activity.RESULT_OK,returnIntent)
        finish()
    }

    private fun doQuizAgain() {

        MaterialStyledDialog.Builder(this@ResultActivity)
            .setTitle("Do quiz again?")
            .setDescription("Do you really want to delete this data?")
            .setIcon(R.drawable.ic_mood_white_24dp)
            .setNegativeText("No")
            .onNegative { dialog, which -> dialog.dismiss() }
            .setPositiveText("Yes")
            .onPositive { dialog, which ->

                val returnIntent = Intent()
                returnIntent.putExtra("action","doquizagain")
                setResult(Activity.RESULT_OK,returnIntent)
                finish()
            }
            .show()
    }

    override fun onDestroy() {
        LocalBroadcastManager.getInstance(this@ResultActivity)
            .unregisterReceiver(backToQuestion)
        super.onDestroy()
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_result)

        LocalBroadcastManager.getInstance(this@ResultActivity)
            .registerReceiver(backToQuestion, IntentFilter(Common.KEY_BACK_FROM_RESULT))

        toolbar.title = "Result"
        setSupportActionBar(toolbar)

        supportActionBar!!.setDisplayHomeAsUpEnabled(true)
        supportActionBar!!.setDisplayShowHomeEnabled(true)

        //
        txt_timer.text = (java.lang.String.format(
            "%02d:%02d",
            TimeUnit.MILLISECONDS.toMinutes(Common.timer.toLong()),
            TimeUnit.MILLISECONDS.toSeconds(Common.timer.toLong()) - TimeUnit.MINUTES.toSeconds(
                TimeUnit.MILLISECONDS.toMinutes(
                    Common.timer.toLong()
                )
            )
        ))
        txt_right_answer.text = "${Common.right_answer_count}/${Common.questionList.size}"

        btn_filter_total.text = "${Common.questionList.size}"
        btn_filter_total.text = "${Common.right_answer_count}"
        btn_filter_total.text = "${Common.wrong_answer_count}"
        btn_filter_total.text = "${Common.no_answer_count}"

        val percent = Common.right_answer_count*100/Common.questionList.size
        if (percent > 80)
            txt_result.text = "Excellent!"
        else if (percent > 65)
            txt_result.text = "Good!"
        else if (percent > 50)
            txt_result.text = "Fair!"
        else
            txt_result.text = "Bad!"

        // Event Button
        btn_filter_total.setOnClickListener{
            val adapter = ResultGridAdapter(this,Common.answerSheetList)
            recycler_result.adapter = adapter
        }

        btn_filter_no_answer.setOnClickListener{
            Common.answerSheetListFiltered.clear()

            for (currentQuestion in Common.answerSheetList)
                if (currentQuestion.type == Common.ANSWER_TYPE.NO_ANSWER)
                    Common.answerSheetListFiltered.add(currentQuestion)
            val adapter = ResultGridAdapter(this,Common.answerSheetListFiltered)
            recycler_result.adapter = adapter
        }

        btn_filter_wrong.setOnClickListener{
            Common.answerSheetListFiltered.clear()

            for (currentQuestion in Common.answerSheetList)
                if (currentQuestion.type == Common.ANSWER_TYPE.WRONG_ANSWER)
                    Common.answerSheetListFiltered.add(currentQuestion)
            val adapter = ResultGridAdapter(this,Common.answerSheetListFiltered)
            recycler_result.adapter = adapter
        }

        btn_filter_right.setOnClickListener{
            Common.answerSheetListFiltered.clear()

            for (currentQuestion in Common.answerSheetList)
                if (currentQuestion.type == Common.ANSWER_TYPE.RIGHT_ANSWER)
                    Common.answerSheetListFiltered.add(currentQuestion)
            val adapter = ResultGridAdapter(this,Common.answerSheetListFiltered)
            recycler_result.adapter = adapter
        }

        // Set Adapter
        val adapter = ResultGridAdapter(this,Common.answerSheetList)
        recycler_result.setHasFixedSize(true)
        recycler_result.layoutManager = GridLayoutManager(this,4)
        recycler_result.addItemDecoration(SpacesItemDecoration(4))
        recycler_result.adapter = adapter

    }
}
</code>```

答:
You have 3 activity but something you show there are 2 activity by the way ,if there is another activity you must add it to manifest
You have these activities

```<code>ResultActivity
CategoryActivity
QuestionActivity
</code>```

Your manifest has 2 of them

```<code>CategoryActivity
QuestionActivity
</code>```

correct manifest is

```<code><?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.ecosense">

    <uses-permission android:name="android.permission.INTERNET"/>

    <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
        <activity android:name=".ResultActivity"
                  android:label="activity_result">
        </activity>
        <activity
                android:name=".QuestionActivity"
                android:label="title_activity_question">
        </activity>
        <activity android:name=".CategoryActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>

</manifest>
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I'm stuck with some code for school. I followed a tutorial and feel like I have 100% the same (checked multiple times). But still I get an error. Android Studio doesn't show any mistakes.

Thanks a lot for any help!

I get the following error:

   --------- beginning of crash
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.ecosense, PID: 4840
    android.content.ActivityNotFoundException: Unable to find explicit activity class {com.example.ecosense/com.example.ecosense.ResultActivity}; have you declared this activity in your AndroidManifest.xml?
        at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:2005)
        at android.app.Instrumentation.execStartActivity(Instrumentation.java:1673)
        at android.app.Activity.startActivityForResult(Activity.java:4586)
        at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:767)
        at android.app.Activity.startActivityForResult(Activity.java:4544)
        at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:754)
        at com.example.ecosense.QuestionActivity.finishGame(QuestionActivity.kt:318)
        at com.example.ecosense.QuestionActivity.access$finishGame(QuestionActivity.kt:44)
        at com.example.ecosense.QuestionActivity$onOptionsItemSelected$2.onClick(QuestionActivity.kt:375)
        at com.afollestad.materialdialogs.MaterialDialog.onClick(MaterialDialog.java:367)
        at android.view.View.performClick(View.java:6597)
        at android.view.View.performClickInternal(View.java:6574)
        at android.view.View.access$3100(View.java:778)
        at android.view.View$PerformClick.run(View.java:25885)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

And this is my QuestionActivity class.

package com.example.ecosense

import android.app.Activity
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Bundle
import android.os.CountDownTimer
import android.support.constraint.ConstraintLayout
import android.support.design.widget.Snackbar
import android.support.design.widget.NavigationView
import android.support.v4.content.LocalBroadcastManager
import android.support.v4.view.GravityCompat
import android.support.v4.view.ViewPager
import android.support.v4.widget.DrawerLayout
import android.support.v7.app.ActionBarDrawerToggle
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.GridLayoutManager
import android.support.v7.widget.RecyclerView
import android.text.TextUtils
import android.view.Gravity
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.Button
import android.widget.TextView
import com.example.ecosense.Adapter.GridAnswerAdapter
import com.example.ecosense.Adapter.MyFragmentAdapter
import com.example.ecosense.Adapter.QuestionListHelperAdapter
import com.github.javiersantos.materialstyleddialogs.MaterialStyledDialog
import com.example.ecosense.Common.Common
import com.example.ecosense.Common.SpacesItemDecoration
import com.example.ecosense.DBHelper.DBHelper
import com.example.ecosense.Model.CurrentQuestion
import com.google.gson.Gson
import kotlinx.android.synthetic.main.activity_question.*
import kotlinx.android.synthetic.main.app_bar_question.*
import kotlinx.android.synthetic.main.content_question.*
import org.w3c.dom.Text
import java.lang.StringBuilder
import java.util.concurrent.TimeUnit

class QuestionActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {

    val CODE_GET_RESULT = 9999

    lateinit var countDownTimer: CountDownTimer

    var time_play = Common.TOTAL_TIME

    var isAnswerModeView = false

    lateinit var adapter: GridAnswerAdapter

    lateinit var questionHelperAdapter: QuestionListHelperAdapter

    lateinit var txt_wrong_answer: TextView

    internal var goToQuestionNum: BroadcastReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            if (intent!!.action!!.toString() == Common.KEY_GO_TO_QUESTION) {
                val question = intent!!.getIntExtra(Common.KEY_GO_TO_QUESTION, -1)
                if (question != -1)
                    view_pager.currentItem = question

                drawer_layout.closeDrawer(Gravity.LEFT)
            }
        }

    }

    override fun onDestroy() {
        LocalBroadcastManager.getInstance(this).unregisterReceiver(goToQuestionNum)
        if (countDownTimer != null)
            countDownTimer!!.cancel()
        if (Common.fragmentList != null)
            Common.fragmentList.clear()
        if (Common.answerSheetList != null)
            Common.answerSheetList.clear()
        super.onDestroy()
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_question)
        setSupportActionBar(toolbar)

        LocalBroadcastManager.getInstance(this)
            .registerReceiver(goToQuestionNum, IntentFilter(Common.KEY_GO_TO_QUESTION))

        val toggle = ActionBarDrawerToggle(
            this, drawer_layout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close
        )
        drawer_layout.addDrawerListener(toggle)
        toggle.syncState()

        nav_view.setNavigationItemSelectedListener(this)

        val recycler_helper_answer_sheet =
            nav_view.getHeaderView(0).findViewById<View>(R.id.answer_sheet) as RecyclerView
        recycler_helper_answer_sheet.layoutManager = GridLayoutManager(this, 3)
        recycler_helper_answer_sheet.setHasFixedSize(true)
        recycler_helper_answer_sheet.addItemDecoration(SpacesItemDecoration(2))

        val btn_done = nav_view.getHeaderView(0).findViewById<View>(R.id.btn_done) as Button
        btn_done.setOnClickListener {
            if (!isAnswerModeView)
            {
                MaterialStyledDialog.Builder(this@QuestionActivity)
                    .setTitle("Finish?")
                    .setDescription("Do you really want to finish?")
                    .setIcon(R.drawable.ic_mood_white_24dp)
                    .setNegativeText("No")
                    .onNegative { dialog, which -> dialog.dismiss() }
                    .setPositiveText("Yes")
                    .onPositive { dialog, which -> finishGame()
                     drawer_layout.closeDrawer(Gravity.LEFT)}
                    .show()

            }
            else {
                finishGame()

            }
        }

        //Get Question base on Category
        genQuestion()

        if (Common.questionList.size > 0) {
            //Show Timer, Right Answer text view
            txt_timer.visibility = View.VISIBLE
            txt_right_answer.visibility = View.VISIBLE

            countTimer()

            //Gen item for grid_answer
            genItems()
            grid_answer.setHasFixedSize(true)
            if (Common.questionList.size > 0)
                grid_answer.layoutManager = GridLayoutManager(
                    this,
                    if (Common.questionList.size > 5) Common.questionList.size / 2 else Common.questionList.size
                )
            adapter = GridAnswerAdapter(this, Common.answerSheetList)

            grid_answer.adapter = adapter

            //Gen fragment list
            genFragmentList()

            val fragmentAdapter = MyFragmentAdapter(supportFragmentManager, this, Common.fragmentList)
            view_pager.offscreenPageLimit = Common.questionList.size
            view_pager.adapter = fragmentAdapter // Bind question to View Pager

            sliding_tabs.setupWithViewPager(view_pager)

            //Event
            view_pager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {

                val SCROLLING_RIGHT = 0
                val SCROLLING_LEFT = 1
                val SCROLLING_UNDETERMINED = 2

                var currentScrollDirection = SCROLLING_UNDETERMINED

                private val isScrollDirectionUndetermined: Boolean
                    get() = currentScrollDirection == SCROLLING_UNDETERMINED
                private val isScrollDirectionRight: Boolean
                    get() = currentScrollDirection == SCROLLING_RIGHT
                private val isScrollDirectionLeft: Boolean
                    get() = currentScrollDirection == SCROLLING_LEFT

                private fun setScrollingDirection(positionOffset: Float) {
                    if (1 - positionOffset >= 0.5)
                        this.currentScrollDirection = SCROLLING_RIGHT
                    else if (1 - positionOffset <= 0.5)
                        this.currentScrollDirection = SCROLLING_LEFT

                }

                override fun onPageScrollStateChanged(p0: Int) {
                    if (p0 == ViewPager.SCROLL_STATE_IDLE)
                        this.currentScrollDirection = SCROLLING_UNDETERMINED
                }

                override fun onPageScrolled(p0: Int, p1: Float, p2: Int) {
                    if (isScrollDirectionUndetermined)
                        setScrollingDirection(p1)
                }

                override fun onPageSelected(p0: Int) {

                    val questionFragment: QuestionFragment
                    var position = 0
                    if (p0 > 0) {
                        if (isScrollDirectionRight) {
                            questionFragment = Common.fragmentList[p0 - 1]
                            position = p0 - 1
                        } else if (isScrollDirectionLeft) {
                            questionFragment = Common.fragmentList[p0 + 1]
                            position = p0 + 1
                        } else {
                            questionFragment = Common.fragmentList[p0]
                        }
                    } else {
                        questionFragment = Common.fragmentList[0]
                        position = 0
                    }

                    if (Common.answerSheetList[position].type == Common.ANSWER_TYPE.NO_ANSWER) {
                        // If you want to show correct answer, enable it
                        val question_state = questionFragment.selectedAnswer()
                        Common.answerSheetList[position] = question_state
                        adapter.notifyDataSetChanged()
                        questionHelperAdapter.notifyDataSetChanged()

                        countCorrectAnswer()

                        txt_right_answer.text = ("${Common.right_answer_count} / ${Common.questionList.size}")
                        txt_wrong_answer.text = "${Common.wrong_answer_count}"

                        if (question_state.type != Common.ANSWER_TYPE.NO_ANSWER) {
                            questionFragment.showCorrectAnswer()
                            questionFragment.disableAnswer()
                        }
                    }
                }

            })

            txt_right_answer.text = "${Common.right_answer_count}/${Common.questionList.size}"
            questionHelperAdapter = QuestionListHelperAdapter(this, Common.answerSheetList)
            recycler_helper_answer_sheet.adapter = questionHelperAdapter
        }
    }

    private fun countCorrectAnswer() {
        Common.right_answer_count = 0 // Reset
        Common.wrong_answer_count = 0

        for (item in Common.answerSheetList)
            if (item.type == Common.ANSWER_TYPE.RIGHT_ANSWER)
                Common.right_answer_count++
            else if (item.type == Common.ANSWER_TYPE.WRONG_ANSWER)
                Common.wrong_answer_count++
    }

    private fun genFragmentList() {
        for (i in Common.questionList.indices) {
            val bundle = Bundle()
            bundle.putInt("index", i)
            val fragment = QuestionFragment()
            fragment.arguments = bundle

            Common.fragmentList.add(fragment)
        }
    }

    private fun genItems() {
        for (i in Common.questionList.indices)
            Common.answerSheetList.add(CurrentQuestion(i, Common.ANSWER_TYPE.NO_ANSWER)) // No answer for all questions
    }

    private fun countTimer() {
        countDownTimer = object : CountDownTimer(Common.TOTAL_TIME.toLong(), 1000) {
            override fun onFinish() {
                finishGame()
            }

            override fun onTick(interval: Long) {
                txt_timer.text = (java.lang.String.format(
                    "%02d:%02d",
                    TimeUnit.MILLISECONDS.toMinutes(interval),
                    TimeUnit.MILLISECONDS.toSeconds(interval) - TimeUnit.MINUTES.toSeconds(
                        TimeUnit.MILLISECONDS.toMinutes(
                            interval
                        )
                    )
                ))
                time_play -= 1000
            }

        }.start()
    }

    private fun finishGame() {
        val position = view_pager.currentItem
        val questionFragment = Common.fragmentList[position]

        val question_state = questionFragment.selectedAnswer()
        Common.answerSheetList[position] = question_state
        adapter.notifyDataSetChanged()
        questionHelperAdapter.notifyDataSetChanged()

        countCorrectAnswer()

        txt_right_answer.text = ("${Common.right_answer_count} / ${Common.questionList.size}")
        txt_wrong_answer.text = "${Common.wrong_answer_count}"

        if (question_state.type != Common.ANSWER_TYPE.NO_ANSWER) {
            questionFragment.showCorrectAnswer()
            questionFragment.disableAnswer()
        }

        val intent = Intent(this@QuestionActivity, ResultActivity::class.java)
        Common.timer = Common.TOTAL_TIME - time_play
        Common.no_answer_count = Common.questionList.size - (Common.right_answer_count + Common.wrong_answer_count)
        Common.data_question = StringBuilder(Gson().toJson(Common.answerSheetList))

        startActivityForResult(intent, CODE_GET_RESULT)

    }

    private fun genQuestion() {
        Common.questionList = DBHelper.getInstance(this)
            .getQuestionByCategory(Common.selectedCategory!!.id)

        if (Common.questionList.size == 0) {
            MaterialStyledDialog.Builder(this)
                .setTitle("Oppps!")
                .setIcon(R.drawable.ic_sentiment_very_dissatisfied_black_24dp)
                .setDescription("We don't have any question in this ${Common.selectedCategory!!.name} category")
                .setPositiveText("OK")
                .onPositive { dialog, which ->
                    dialog.dismiss()
                    finish()
                }.show()
        }
    }

    override fun onBackPressed() {
        val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
        if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
            drawerLayout.closeDrawer(GravityCompat.START)
        } else {
            this.finish() // Close this activity when click on back button
            super.onBackPressed()
        }
    }

    override fun onPrepareOptionsMenu(menu: Menu?): Boolean {
        val item = menu!!.findItem(R.id.menu_wrong_answer)
        val layout = item.actionView as ConstraintLayout
        txt_wrong_answer = layout.findViewById(R.id.txt_wrong_answer) as TextView
        txt_wrong_answer.text = 0.toString()
        return true
    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        // Inflate the menu; this adds items to the action bar if it is present.
        menuInflater.inflate(R.menu.question, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.menu_done -> {
                if (!isAnswerModeView) {
                    MaterialStyledDialog.Builder(this@QuestionActivity)
                        .setTitle("Finish?")
                        .setDescription("Do you really want to finish?")
                        .setIcon(R.drawable.ic_mood_white_24dp)
                        .setNegativeText("No")
                        .onNegative { dialog, which -> dialog.dismiss() }
                        .setPositiveText("Yes")
                        .onPositive { dialog, which ->
                            finishGame()
                            drawer_layout.closeDrawer(Gravity.LEFT)
                        }.show()

                } else {
                    finishGame()
                }
            }
        }
        return true

    }

    override fun onNavigationItemSelected(item: MenuItem): Boolean {
        // Handle navigation view item clicks here.
        when (item.itemId) {
            R.id.nav_home -> {
                // Handle the camera action
            }
            R.id.nav_gallery -> {

            }
            R.id.nav_slideshow -> {

            }
            R.id.nav_tools -> {

            }
            R.id.nav_share -> {

            }
            R.id.nav_send -> {

            }
        }
        val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
        drawerLayout.closeDrawer(GravityCompat.START)
        return true
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == CODE_GET_RESULT)
        {
            if (resultCode == Activity.RESULT_OK)
            {
                val action = data!!.getStringExtra("action")
                if (action == null || TextUtils.isEmpty(action))
                {
                    val questionIndex = data.getIntExtra(Common.KEY_BACK_FROM_RESULT, -1)
                    view_pager.currentItem = questionIndex

                    isAnswerModeView = true
                    countDownTimer!!.cancel()

                    txt_wrong_answer.visibility = View.GONE
                    txt_right_answer.visibility = View.GONE
                    txt_timer.visibility = View.GONE
                }
                else
                {
                    if (action.equals("doquizagain"))
                        {
                            view_pager.currentItem = 0
                            isAnswerModeView = false

                        txt_wrong_answer.visibility = View.VISIBLE
                        txt_right_answer.visibility = View.VISIBLE
                        txt_timer.visibility = View.VISIBLE

                        for (i in Common.fragmentList.indices) {
                            Common.fragmentList[i].resetQuestion()
                        }

                        for (i in Common.answerSheetList.indices)
                            Common.answerSheetList[i].type = Common.ANSWER_TYPE.NO_ANSWER

                        adapter.notifyDataSetChanged()
                        questionHelperAdapter.notifyDataSetChanged()

                        countTimer()

                    } else if (action.equals("viewanswer"))
                    {
                        view_pager.currentItem = 0
                        isAnswerModeView = true
                        countDownTimer!!.cancel()

                        txt_wrong_answer.visibility = View.GONE
                        txt_right_answer.visibility = View.GONE
                        txt_timer.visibility = View.GONE

                        for (i in Common.fragmentList.indices)
                        {
                            Common.fragmentList[i].showCorrectAnswer()
                            Common.fragmentList[i].disableAnswer()
                        }
                        }
                    }
                }
            }
    }
}

My ResultActivity class:

package com.example.ecosense

import android.app.Activity
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.support.v4.content.LocalBroadcastManager
import android.support.v7.widget.GridLayoutManager
import android.view.Gravity
import android.view.Menu
import android.view.MenuItem
import com.example.ecosense.Adapter.ResultGridAdapter
import com.example.ecosense.Common.Common
import com.example.ecosense.Common.SpacesItemDecoration
import com.github.javiersantos.materialstyleddialogs.MaterialStyledDialog
import kotlinx.android.synthetic.main.activity_question.*
import kotlinx.android.synthetic.main.activity_result.*
import kotlinx.android.synthetic.main.activity_result.txt_right_answer
import kotlinx.android.synthetic.main.content_question.*
import java.util.concurrent.TimeUnit

class ResultActivity : AppCompatActivity() {

    internal var backToQuestion:BroadcastReceiver = object:BroadcastReceiver(){
        override fun onReceive(context: Context?, intent: Intent?) {
            if (intent!!.action!!.toString() == Common.KEY_BACK_FROM_RESULT)
            {
                val questionIndex = intent.getIntExtra(Common.KEY_BACK_FROM_RESULT,-1)
                goBackActivityWithQuestionIndex(questionIndex)
            }
        }

    }

    private fun goBackActivityWithQuestionIndex(questionIndex: Int) {
        val returnIntent = Intent()
        returnIntent.putExtra(Common.KEY_BACK_FROM_RESULT,questionIndex)
        setResult(Activity.RESULT_OK,returnIntent)
        finish()

    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.menu_result,menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem?): Boolean {
        when(item!!.itemId)
        {
            R.id.menu_do_quiz_again -> doQuizAgain()
            R.id.menu_view_answer -> viewAnswer()
            android.R.id.home -> {
                val intent = Intent(applicationContext,CategoryActivity::class.java)
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
                startActivity(intent) // Go back to category when click on back arrow in result activity
            }
        }
        return true
    }

    private fun viewAnswer() {
        val returnIntent = Intent()
        returnIntent.putExtra("action","viewanswer")
        setResult(Activity.RESULT_OK,returnIntent)
        finish()
    }

    private fun doQuizAgain() {

        MaterialStyledDialog.Builder(this@ResultActivity)
            .setTitle("Do quiz again?")
            .setDescription("Do you really want to delete this data?")
            .setIcon(R.drawable.ic_mood_white_24dp)
            .setNegativeText("No")
            .onNegative { dialog, which -> dialog.dismiss() }
            .setPositiveText("Yes")
            .onPositive { dialog, which ->

                val returnIntent = Intent()
                returnIntent.putExtra("action","doquizagain")
                setResult(Activity.RESULT_OK,returnIntent)
                finish()
            }
            .show()
    }

    override fun onDestroy() {
        LocalBroadcastManager.getInstance(this@ResultActivity)
            .unregisterReceiver(backToQuestion)
        super.onDestroy()
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_result)

        LocalBroadcastManager.getInstance(this@ResultActivity)
            .registerReceiver(backToQuestion, IntentFilter(Common.KEY_BACK_FROM_RESULT))

        toolbar.title = "Result"
        setSupportActionBar(toolbar)

        supportActionBar!!.setDisplayHomeAsUpEnabled(true)
        supportActionBar!!.setDisplayShowHomeEnabled(true)

        //
        txt_timer.text = (java.lang.String.format(
            "%02d:%02d",
            TimeUnit.MILLISECONDS.toMinutes(Common.timer.toLong()),
            TimeUnit.MILLISECONDS.toSeconds(Common.timer.toLong()) - TimeUnit.MINUTES.toSeconds(
                TimeUnit.MILLISECONDS.toMinutes(
                    Common.timer.toLong()
                )
            )
        ))
        txt_right_answer.text = "${Common.right_answer_count}/${Common.questionList.size}"

        btn_filter_total.text = "${Common.questionList.size}"
        btn_filter_total.text = "${Common.right_answer_count}"
        btn_filter_total.text = "${Common.wrong_answer_count}"
        btn_filter_total.text = "${Common.no_answer_count}"

        val percent = Common.right_answer_count*100/Common.questionList.size
        if (percent > 80)
            txt_result.text = "Excellent!"
        else if (percent > 65)
            txt_result.text = "Good!"
        else if (percent > 50)
            txt_result.text = "Fair!"
        else
            txt_result.text = "Bad!"

        // Event Button
        btn_filter_total.setOnClickListener{
            val adapter = ResultGridAdapter(this,Common.answerSheetList)
            recycler_result.adapter = adapter
        }

        btn_filter_no_answer.setOnClickListener{
            Common.answerSheetListFiltered.clear()

            for (currentQuestion in Common.answerSheetList)
                if (currentQuestion.type == Common.ANSWER_TYPE.NO_ANSWER)
                    Common.answerSheetListFiltered.add(currentQuestion)
            val adapter = ResultGridAdapter(this,Common.answerSheetListFiltered)
            recycler_result.adapter = adapter
        }

        btn_filter_wrong.setOnClickListener{
            Common.answerSheetListFiltered.clear()

            for (currentQuestion in Common.answerSheetList)
                if (currentQuestion.type == Common.ANSWER_TYPE.WRONG_ANSWER)
                    Common.answerSheetListFiltered.add(currentQuestion)
            val adapter = ResultGridAdapter(this,Common.answerSheetListFiltered)
            recycler_result.adapter = adapter
        }

        btn_filter_right.setOnClickListener{
            Common.answerSheetListFiltered.clear()

            for (currentQuestion in Common.answerSheetList)
                if (currentQuestion.type == Common.ANSWER_TYPE.RIGHT_ANSWER)
                    Common.answerSheetListFiltered.add(currentQuestion)
            val adapter = ResultGridAdapter(this,Common.answerSheetListFiltered)
            recycler_result.adapter = adapter
        }

        // Set Adapter
        val adapter = ResultGridAdapter(this,Common.answerSheetList)
        recycler_result.setHasFixedSize(true)
        recycler_result.layoutManager = GridLayoutManager(this,4)
        recycler_result.addItemDecoration(SpacesItemDecoration(4))
        recycler_result.adapter = adapter

    }
}

Body:
You have 3 activity but something you show there are 2 activity by the way ,if there is another activity you must add it to manifest
You have these activities

ResultActivity
CategoryActivity
QuestionActivity

Your manifest has 2 of them

CategoryActivity
QuestionActivity

correct manifest is

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.ecosense">

    <uses-permission android:name="android.permission.INTERNET"/>

    <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
        <activity android:name=".ResultActivity"
                  android:label="activity_result">
        </activity>
        <activity
                android:name=".QuestionActivity"
                android:label="title_activity_question">
        </activity>
        <activity android:name=".CategoryActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>

</manifest>


问:
Problem with calculating line intersections
I am trying to display the points of intersecting lines, but the calculated points are between the actual intersectings.

(https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection)

I have checked the formulars multiple times and used another formula for calculating the intersecting points x, y [x3+u*(x4-x3), y3+u*(y4-y3)] instead of [x1+t*(x2-x1), y1+t*(y2-y1)], but that just made the points somewhere really wrong

("d" is not referenced on the wikipedia page and is just the divisor for the formulars of t and u)

Function for calculating the intersection

    def checkcol(self, startObs, endObs):
        x1, y1 = startObs
        x2, y2 = endObs
        x3, y3 = run.lamp
        x4, y4 = self.endpoint

        d = (x1-x2)*(y3-y4)-(y1-y2)*(x3-x4)
        t = ((x1-x3)*(y3-y4)-(y1-y3)*(x3-x4))/d
        u = ((x1-x2)*(y1-y3)-(y1-y2)*(x1-x3))/d
        if 0 < t < 1 and 1 > u > 0:
            pygame.draw.circle(run.screen, pygame.Color('green'), (round(x1+t*(x2-x1)), round(y1+t*(y2-y1))), 3)
```

<p>The whole code</p>

<pre class="lang-py prettyprint-override"><code>import pygame
import sys
import math
import random as rd

class Obs(object):
    def __init__(self, startp, endp):
        self.startp = startp
        self.endp = endp

    def drawww(self):
        pygame.draw.line(run.screen, pygame.Color('red'), (self.startp), (self.endp))
        for ray in run.lines:
            ray.checkcol(self.startp, self.endp)

class rays(object):
    def __init__(self, endpoint):
        self.width = 2
        self.endpoint = endpoint

    def draww(self):
        pygame.draw.line(run.screen, pygame.Color('white'), run.lamp, self.endpoint, 2)

    def moveEnd(self, xoff, yoff):
        self.endpoint[0] += xoff
        self.endpoint[1] += yoff

    def checkcol(self, startObs, endObs):
        x1, y1 = startObs
        x2, y2 = endObs
        x3, y3 = run.lamp
        x4, y4 = self.endpoint

        d = (x1-x2)*(y3-y4)-(y1-y2)*(x3-x4)
        t = ((x1-x3)*(y3-y4)-(y1-y3)*(x3-x4))/d
        u = ((x1-x2)*(y1-y3)-(y1-y2)*(x1-x3))/d
        if 0 < t < 1 and 1 > u > 0:
            pygame.draw.circle(run.screen, pygame.Color('green'), (round(x1+t*(x2-x1)), round(y1+t*(y2-y1))), 3)

class Control(object):
    def __init__(self):
        self.winw = 800
        self.winh = 800
        self.screen = pygame.display.set_mode((self.winw, self.winh))
        self.fps = 60
        self.clock = pygame.time.Clock()
        self.lamp = [400, 400]
        self.lampr = 13
        self.lines = []
        self.r = 10
        self.Obs = [Obs((rd.randint(0, self.winw), rd.randint(0, self.winh)),
                        (rd.randint(0, self.winw), rd.randint(0, self.winh))) for i in range(5)]
        self.done = False

    def event_loop(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.done = True
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_F5:
                    self.__init__()

        if pygame.mouse.get_pressed() == (1, 0, 0):
            self.lamp = (pygame.mouse.get_pos())
            for line in self.lines:
                line.moveEnd(pygame.mouse.get_rel()[0], pygame.mouse.get_rel()[1])

    def draw(self):
        self.screen.fill((pygame.Color('black')))
        pygame.draw.circle(self.screen, pygame.Color('white'), self.lamp, self.lampr)
        for line in self.lines:
            line.draww()
        for obs in self.Obs:
            obs.drawww()

    def createlines(self):
        self.lines.clear()
        for angle in range(0, 361, 9):
            self.lines.append(rays([self.lamp[0] + 1200 * math.cos(angle), self.lamp[1] + 1200 * math.sin(angle)]))

    def main_loop(self):
        while not self.done:
            self.event_loop()
            self.createlines()
            self.draw()
            pygame.display.update()
            self.clock.tick(self.fps)
            pygame.display.set_caption(f"Draw  FPS: {self.clock.get_fps()}")

if __name__ == '__main__':
    run = Control()
    run.main_loop()
    pygame.quit()
    sys.exit()

</code>```

Expected the points of intersecting to be at the actual points of intersection.

答:
To find the intersection points of 2 rays or line segments in two-dimensional space, I use vector arithmetic and the following algorithm:

P     ... point on the 1. line
R     ... direction of the 1. line

Q     ... point on the 2. line
S     ... direction of the 2. line

alpha ... angle between Q-P and R
beta  ... angle between R and S

gamma  =  180° - alpha - beta

h  =  | Q - P | * sin(alpha)
u  =  h / sin(beta)

t  = | Q - P | * sin(gamma) / sin(beta)

t  =  dot(Q-P, (S.y, -S.x)) / dot(R, (S.y, -S.x))  =  determinant(mat2(Q-P, S)) / determinant(mat2(R, S))
u  =  dot(Q-P, (R.y, -R.x)) / dot(R, (S.y, -S.x))  =  determinant(mat2(Q-P, R)) / determinant(mat2(R, S))

X  =  P + R * t  =  Q + S * u
```
<p>See also Line–line intersection</p>
<p>If <code>t == 1</code>, then <code>X = P + R</code>. This can be used to assess whether the intersection is on a line segment.<br />
If a line is defined through the 2 points <code>L1</code> and <code>L2</code>, it can be defined that <code>P = L1</code> and <code>R = L2-L1</code>. Therefore the point of intersection (<code>X</code>) lies on the line segment from <code>L1</code> to <code>L2</code> if <code>0 <= t <= 1</code>.<br />
The same relation applies to <code>u</code> and <code>S</code>.</p>
<p>The following function implements the above algorithm using <code>pygame.math.Vector2</code> objects of the <code>pygame.math</code> module:</p>
<pre class="lang-py prettyprint-override"><code>def intersect_line_line_vec2(startObs, endObs, origin, endpoint):
    P = pygame.Vector2(startObs)
    R = (endObs - P)
    Q = pygame.Vector2(origin)
    S = (endpoint - Q)
    d = R.dot((S.y, -S.x))
    if d == 0:
        return None
    t = (Q-P).dot((S.y, -S.x)) / d
    u = (Q-P).dot((R.y, -R.x)) / d
    if 0 <= t <= 1 and 0 <= u <= 1:
        X  =  P + R * t
        return (X.x, X.y)
    return None
</code>```

The same algorithm without the use of the pygame.math module, less readable but more or less the same:

def intersect_line_line(P0, P1, Q0, Q1):
    d = (P1[0]-P0[0]) * (Q1[1]-Q0[1]) + (P1[1]-P0[1]) * (Q0[0]-Q1[0])
    if d == 0:
        return None
    t = ((Q0[0]-P0[0]) * (Q1[1]-Q0[1]) + (Q0[1]-P0[1]) * (Q0[0]-Q1[0])) / d
    u = ((Q0[0]-P0[0]) * (P1[1]-P0[1]) + (Q0[1]-P0[1]) * (P0[0]-P1[0])) / d
    if 0 <= t <= 1 and 0 <= u <= 1:
        return P1[0] * t + P0[0] * (1-t), P1[1] * t + P0[1] * (1-t)
    return None
```
<hr />
<p>Applied to your code, this means:</p>
<pre class="lang-py prettyprint-override"><code>class rays(object):

    # [...]

    def checkcol(self, startObs, endObs):
        P = pygame.Vector2(startObs)
        R = (endObs - P).normalize()
        Q = pygame.Vector2(run.lamp)
        S = (self.endpoint - Q).normalize()
        d = R.dot((S.y, -S.x))
        if R.dot((S.y, -S.x)) == 0:
            return
        t  =  (Q-P).dot((S.y, -S.x)) / d
        u  =  (Q-P).dot((R.y, -R.x)) / d
        if 0 <= t <= 1 and 0 <= u <= 1:
            X = P + R * t
            pygame.draw.circle(run.screen, pygame.Color('green'), (round(X.x), round(X.y)), 3)
</code>```

Minimal example:  repl.it/@Rabbid76/PyGame-IntersectLines

import pygame
import math
import random

def intersect_line_line_vec2(startObs, endObs, origin, endpoint):
    P = pygame.Vector2(startObs)
    R = (endObs - P)
    Q = pygame.Vector2(origin)
    S = (endpoint - Q)
    d = R.dot((S.y, -S.x))
    if d == 0:
        return None
    t = (Q-P).dot((S.y, -S.x)) / d
    u = (Q-P).dot((R.y, -R.x)) / d
    if 0 <= t <= 1 and 0 <= u <= 1:
        X  =  P + R * t
        return (X.x, X.y)
    return None

def intersect_line_line(P0, P1, Q0, Q1):
    d = (P1[0]-P0[0]) * (Q1[1]-Q0[1]) + (P1[1]-P0[1]) * (Q0[0]-Q1[0])
    if d == 0:
        return None
    t = ((Q0[0]-P0[0]) * (Q1[1]-Q0[1]) + (Q0[1]-P0[1]) * (Q0[0]-Q1[0])) / d
    u = ((Q0[0]-P0[0]) * (P1[1]-P0[1]) + (Q0[1]-P0[1]) * (P0[0]-P1[0])) / d
    if 0 <= t <= 1 and 0 <= u <= 1:
        return P1[0] * t + P0[0] * (1-t), P1[1] * t + P0[1] * (1-t)
    return None

def createRays(center):
    return [(center[0] + 1200 * math.cos(angle), center[1] + 1200 * math.sin(angle)) for angle in range(0, 360, 10)]

def createObstacles(surface):
    w, h = surface.get_size()
    return [((random.randrange(w), random.randrange(h)), (random.randrange(w), random.randrange(h))) for _ in range(5)]

window = pygame.display.set_mode((800, 800))
clock = pygame.time.Clock()

origin = window.get_rect().center
rays = createRays(origin)
obstacles = createObstacles(window)

move_center = True
run = True
while run:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        if event.type == pygame.MOUSEBUTTONDOWN:
            obstacles = createObstacles(window)
        if event.type == pygame.KEYDOWN:
            move_center = not move_center

    if move_center:
        origin = pygame.mouse.get_pos()
        rays = createRays(origin)

    window.fill(0)
    for endpoint in rays:
        pygame.draw.line(window, (128, 128, 128), origin, endpoint)
    pygame.draw.circle(window, (255, 255, 255), origin, 10)
    for start, end in obstacles:
        pygame.draw.line(window, (255, 0, 0), start, end)
        for endpoint in rays:
            pos = intersect_line_line(start, end, origin, endpoint)
            if pos:
                pygame.draw.circle(window, (0, 255, 0), (round(pos[0]), round(pos[1])), 3)
    pygame.display.flip()

pygame.quit()
exit()
```

Body:
I am trying to display the points of intersecting lines, but the calculated points are between the actual intersectings.

(https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection)

I have checked the formulars multiple times and used another formula for calculating the intersecting points x, y [x3+u*(x4-x3), y3+u*(y4-y3)] instead of [x1+t*(x2-x1), y1+t*(y2-y1)], but that just made the points somewhere really wrong

("d" is not referenced on the wikipedia page and is just the divisor for the formulars of t and u)

Function for calculating the intersection

    def checkcol(self, startObs, endObs):
        x1, y1 = startObs
        x2, y2 = endObs
        x3, y3 = run.lamp
        x4, y4 = self.endpoint

        d = (x1-x2)*(y3-y4)-(y1-y2)*(x3-x4)
        t = ((x1-x3)*(y3-y4)-(y1-y3)*(x3-x4))/d
        u = ((x1-x2)*(y1-y3)-(y1-y2)*(x1-x3))/d
        if 0 < t < 1 and 1 > u > 0:
            pygame.draw.circle(run.screen, pygame.Color('green'), (round(x1+t*(x2-x1)), round(y1+t*(y2-y1))), 3)

The whole code

import pygame
import sys
import math
import random as rd

class Obs(object):
    def __init__(self, startp, endp):
        self.startp = startp
        self.endp = endp

    def drawww(self):
        pygame.draw.line(run.screen, pygame.Color('red'), (self.startp), (self.endp))
        for ray in run.lines:
            ray.checkcol(self.startp, self.endp)

class rays(object):
    def __init__(self, endpoint):
        self.width = 2
        self.endpoint = endpoint

    def draww(self):
        pygame.draw.line(run.screen, pygame.Color('white'), run.lamp, self.endpoint, 2)

    def moveEnd(self, xoff, yoff):
        self.endpoint[0] += xoff
        self.endpoint[1] += yoff

    def checkcol(self, startObs, endObs):
        x1, y1 = startObs
        x2, y2 = endObs
        x3, y3 = run.lamp
        x4, y4 = self.endpoint

        d = (x1-x2)*(y3-y4)-(y1-y2)*(x3-x4)
        t = ((x1-x3)*(y3-y4)-(y1-y3)*(x3-x4))/d
        u = ((x1-x2)*(y1-y3)-(y1-y2)*(x1-x3))/d
        if 0 < t < 1 and 1 > u > 0:
            pygame.draw.circle(run.screen, pygame.Color('green'), (round(x1+t*(x2-x1)), round(y1+t*(y2-y1))), 3)

class Control(object):
    def __init__(self):
        self.winw = 800
        self.winh = 800
        self.screen = pygame.display.set_mode((self.winw, self.winh))
        self.fps = 60
        self.clock = pygame.time.Clock()
        self.lamp = [400, 400]
        self.lampr = 13
        self.lines = []
        self.r = 10
        self.Obs = [Obs((rd.randint(0, self.winw), rd.randint(0, self.winh)),
                        (rd.randint(0, self.winw), rd.randint(0, self.winh))) for i in range(5)]
        self.done = False

    def event_loop(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.done = True
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_F5:
                    self.__init__()

        if pygame.mouse.get_pressed() == (1, 0, 0):
            self.lamp = (pygame.mouse.get_pos())
            for line in self.lines:
                line.moveEnd(pygame.mouse.get_rel()[0], pygame.mouse.get_rel()[1])

    def draw(self):
        self.screen.fill((pygame.Color('black')))
        pygame.draw.circle(self.screen, pygame.Color('white'), self.lamp, self.lampr)
        for line in self.lines:
            line.draww()
        for obs in self.Obs:
            obs.drawww()

    def createlines(self):
        self.lines.clear()
        for angle in range(0, 361, 9):
            self.lines.append(rays([self.lamp[0] + 1200 * math.cos(angle), self.lamp[1] + 1200 * math.sin(angle)]))

    def main_loop(self):
        while not self.done:
            self.event_loop()
            self.createlines()
            self.draw()
            pygame.display.update()
            self.clock.tick(self.fps)
            pygame.display.set_caption(f"Draw  FPS: {self.clock.get_fps()}")

if __name__ == '__main__':
    run = Control()
    run.main_loop()
    pygame.quit()
    sys.exit()

Expected the points of intersecting to be at the actual points of intersection.

Body:
To find the intersection points of 2 rays or line segments in two-dimensional space, I use vector arithmetic and the following algorithm:

P     ... point on the 1. line
R     ... direction of the 1. line

Q     ... point on the 2. line
S     ... direction of the 2. line

alpha ... angle between Q-P and R
beta  ... angle between R and S

gamma  =  180° - alpha - beta

h  =  | Q - P | * sin(alpha)
u  =  h / sin(beta)

t  = | Q - P | * sin(gamma) / sin(beta)

t  =  dot(Q-P, (S.y, -S.x)) / dot(R, (S.y, -S.x))  =  determinant(mat2(Q-P, S)) / determinant(mat2(R, S))
u  =  dot(Q-P, (R.y, -R.x)) / dot(R, (S.y, -S.x))  =  determinant(mat2(Q-P, R)) / determinant(mat2(R, S))

X  =  P + R * t  =  Q + S * u

See also Line–line intersection

If t == 1, then X = P + R. This can be used to assess whether the intersection is on a line segment.

If a line is defined through the 2 points L1 and L2, it can be defined that P = L1 and R = L2-L1. Therefore the point of intersection (X) lies on the line segment from L1 to L2 if 0 <= t <= 1.

The same relation applies to u and S.

The following function implements the above algorithm using pygame.math.Vector2 objects of the pygame.math module:

def intersect_line_line_vec2(startObs, endObs, origin, endpoint):
    P = pygame.Vector2(startObs)
    R = (endObs - P)
    Q = pygame.Vector2(origin)
    S = (endpoint - Q)
    d = R.dot((S.y, -S.x))
    if d == 0:
        return None
    t = (Q-P).dot((S.y, -S.x)) / d
    u = (Q-P).dot((R.y, -R.x)) / d
    if 0 <= t <= 1 and 0 <= u <= 1:
        X  =  P + R * t
        return (X.x, X.y)
    return None

The same algorithm without the use of the pygame.math module, less readable but more or less the same:

def intersect_line_line(P0, P1, Q0, Q1):
    d = (P1[0]-P0[0]) * (Q1[1]-Q0[1]) + (P1[1]-P0[1]) * (Q0[0]-Q1[0])
    if d == 0:
        return None
    t = ((Q0[0]-P0[0]) * (Q1[1]-Q0[1]) + (Q0[1]-P0[1]) * (Q0[0]-Q1[0])) / d
    u = ((Q0[0]-P0[0]) * (P1[1]-P0[1]) + (Q0[1]-P0[1]) * (P0[0]-P1[0])) / d
    if 0 <= t <= 1 and 0 <= u <= 1:
        return P1[0] * t + P0[0] * (1-t), P1[1] * t + P0[1] * (1-t)
    return None

Applied to your code, this means:

class rays(object):

    # [...]

    def checkcol(self, startObs, endObs):
        P = pygame.Vector2(startObs)
        R = (endObs - P).normalize()
        Q = pygame.Vector2(run.lamp)
        S = (self.endpoint - Q).normalize()
        d = R.dot((S.y, -S.x))
        if R.dot((S.y, -S.x)) == 0:
            return
        t  =  (Q-P).dot((S.y, -S.x)) / d
        u  =  (Q-P).dot((R.y, -R.x)) / d
        if 0 <= t <= 1 and 0 <= u <= 1:
            X = P + R * t
            pygame.draw.circle(run.screen, pygame.Color('green'), (round(X.x), round(X.y)), 3)

Minimal example:  repl.it/@Rabbid76/PyGame-IntersectLines

import pygame
import math
import random

def intersect_line_line_vec2(startObs, endObs, origin, endpoint):
    P = pygame.Vector2(startObs)
    R = (endObs - P)
    Q = pygame.Vector2(origin)
    S = (endpoint - Q)
    d = R.dot((S.y, -S.x))
    if d == 0:
        return None
    t = (Q-P).dot((S.y, -S.x)) / d
    u = (Q-P).dot((R.y, -R.x)) / d
    if 0 <= t <= 1 and 0 <= u <= 1:
        X  =  P + R * t
        return (X.x, X.y)
    return None

def intersect_line_line(P0, P1, Q0, Q1):
    d = (P1[0]-P0[0]) * (Q1[1]-Q0[1]) + (P1[1]-P0[1]) * (Q0[0]-Q1[0])
    if d == 0:
        return None
    t = ((Q0[0]-P0[0]) * (Q1[1]-Q0[1]) + (Q0[1]-P0[1]) * (Q0[0]-Q1[0])) / d
    u = ((Q0[0]-P0[0]) * (P1[1]-P0[1]) + (Q0[1]-P0[1]) * (P0[0]-P1[0])) / d
    if 0 <= t <= 1 and 0 <= u <= 1:
        return P1[0] * t + P0[0] * (1-t), P1[1] * t + P0[1] * (1-t)
    return None

def createRays(center):
    return [(center[0] + 1200 * math.cos(angle), center[1] + 1200 * math.sin(angle)) for angle in range(0, 360, 10)]

def createObstacles(surface):
    w, h = surface.get_size()
    return [((random.randrange(w), random.randrange(h)), (random.randrange(w), random.randrange(h))) for _ in range(5)]

window = pygame.display.set_mode((800, 800))
clock = pygame.time.Clock()

origin = window.get_rect().center
rays = createRays(origin)
obstacles = createObstacles(window)

move_center = True
run = True
while run:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        if event.type == pygame.MOUSEBUTTONDOWN:
            obstacles = createObstacles(window)
        if event.type == pygame.KEYDOWN:
            move_center = not move_center

    if move_center:
        origin = pygame.mouse.get_pos()
        rays = createRays(origin)

    window.fill(0)
    for endpoint in rays:
        pygame.draw.line(window, (128, 128, 128), origin, endpoint)
    pygame.draw.circle(window, (255, 255, 255), origin, 10)
    for start, end in obstacles:
        pygame.draw.line(window, (255, 0, 0), start, end)
        for endpoint in rays:
            pos = intersect_line_line(start, end, origin, endpoint)
            if pos:
                pygame.draw.circle(window, (0, 255, 0), (round(pos[0]), round(pos[1])), 3)
    pygame.display.flip()

pygame.quit()
exit()


问:
How to save external API's data in a django model?
I am pulling in some JSON data from a external API.

```<code>{
   "id": 1,
   "body": "example json"
},
{
   "id": 2,
   "body": "example json"
}
</code>```

my User model:

```<code>class User(models.Model):
      body = models.CharField(max_length=200)
</code>```

how i can save the json response into my model ?

答:
Save a model defined object by using the Model API

import json

json_result = '''{
   "id": 2,
   "body": "example json"
}'''
data = json.loads(json_result) # first convert to a dict
id = data.get("id") # get the id
body = data.get("body") # get the body
user = User.objects.create(id=id, body=body) # create a User object
user.save() # save it
```

Body:
I am pulling in some JSON data from a external API.

{
   "id": 1,
   "body": "example json"
},
{
   "id": 2,
   "body": "example json"
}

my User model:

class User(models.Model):
      body = models.CharField(max_length=200)

how i can save the json response into my model ?