Skip to content
Snippets Groups Projects
Commit 02fd6411 authored by Axel Glöckner's avatar Axel Glöckner
Browse files

reset

parent 9a3cd082
No related branches found
No related tags found
No related merge requests found
Showing
with 0 additions and 727 deletions
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties
# Default ignored files
/shelf/
/workspace.xml
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="17" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="jbr-17" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>
\ No newline at end of file
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>
\ No newline at end of file
/build
\ No newline at end of file
plugins {
id("com.android.application")
}
android {
namespace = "com.example.laboration3_new"
compileSdk = 34
defaultConfig {
applicationId = "com.example.laboration3_new"
minSdk = 34
targetSdk = 34
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
}
dependencies {
implementation("com.google.code.gson:gson:2.8.8") // adding dependency for gson.
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("com.google.android.material:material:1.10.0")
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
}
\ No newline at end of file
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
\ No newline at end of file
package com.example.laboration3_new;
import android.content.Context;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
assertEquals("com.example.laboration3_new", appContext.getPackageName());
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Laboration3_new"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
\ No newline at end of file
package com.example.laboration3_new;
import android.util.Log;
import com.google.gson.Gson;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
/**
* fetch data of a search suggestion, keeping track of the searches with int id.
*/
public class Fetch {
private int id;
private String searchText;
private int numberOfSuggestions;
private ArrayList<String> data;
public Fetch(int id, String searchText, int numberOfSuggestions){
this.id = id;
this.searchText = searchText;
this.numberOfSuggestions = numberOfSuggestions;
this.data = fetch(searchText);
}
public int getId() {
return id;
}
public ArrayList<String> getSearchSuggestions(){
return this.data;
}
private ArrayList<String> fetch(String searchText){
ArrayList<String> data = new ArrayList<>();
try {
URL url = new URL("https://andla.pythonanywhere.com/getnames/" + id + "/" + searchText);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
if(connection.getResponseCode() == HttpURLConnection.HTTP_OK){
InputStream responseStream = new BufferedInputStream(connection.getInputStream());
InputStreamReader reader = new InputStreamReader(responseStream);
Gson gson = new Gson();
Item item = gson.fromJson(reader, Item.class);
int limit = Math.min(item.getResult().size(), numberOfSuggestions);
data.addAll(item.getResult().subList(0, limit));
connection.disconnect();
}else{
Log.d("Bad Connection", String.valueOf(connection.getResponseCode()));
}
}catch(IOException e){
e.printStackTrace();
Log.d("Exception", e.getMessage());
}
return data;
}
}
\ No newline at end of file
package com.example.laboration3_new;
import android.content.Context;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.View;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.ListPopupWindow;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.ArrayList;
public class InteractiveSearcher extends androidx.appcompat.widget.AppCompatEditText {
private static final int DEFAULT_NUMBER_OF_SUGGESTIONS=10;
private int id=-1;
private int numberOfSuggestions=-1;
private ArrayList<String> mySuggestions;
private MyAdapter myAdapter;
private Fetch fetch;
private ListPopupWindow listPopupWindow;
private Context context;
public InteractiveSearcher(@NonNull Context context) {
super(context);
this.context = context;
init();
}
public InteractiveSearcher(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
this.context = context;
init();
}
public InteractiveSearcher(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.context = context;
init();
}
public void setNumberOfSuggestions(int n){
this.numberOfSuggestions = n;
}
/**
* initialize the adapter, listpopupwindow and the data structure for all suggestions,
* Adding a text watcher and a click-listener.
*/
private void init() {
if(numberOfSuggestions==-1){numberOfSuggestions=DEFAULT_NUMBER_OF_SUGGESTIONS;}
mySuggestions = new ArrayList<>();
myAdapter = new MyAdapter(this.context, mySuggestions);
listPopupWindow = new ListPopupWindow(this.context);
listPopupWindow.setAdapter(myAdapter);
listPopupWindow.setAnchorView(this);
listPopupWindow.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
addTextChangedListener(getTextWatcher());
listPopupWindow.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Row row = (Row) view; // A Row is a view --> we can cast Row on each view.
setText(row.getSuggestion()); // using the getter from Row.
}
});
}
private TextWatcher getTextWatcher(){
return new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
final String input = s.toString().trim();
// open a thread for a network connection/fetching data.
Thread t = new Thread(new Runnable() {
@Override
public void run() {
id++;
fetch = new Fetch(id, input, numberOfSuggestions); // new fetch
mySuggestions = fetch.getSearchSuggestions(); // set our arraylist with suggestions.
post(new Runnable() {
@Override
public void run() {
if(mySuggestions.isEmpty()){ // if we get no search suggestions.
clearWindow();
return;
}
/**
Check if the current id is the same as fetch id. We are doing this
to ensure that we get the correct dataset, as we don't know how
fast each fetch is or how fast the user is typing.
*/
if (id == fetch.getId()) {
/**
Setting data will start creating Rows, and the Rows will be
drawn with help of onDraw in the Row class.
*/
myAdapter.setData(mySuggestions); // set available data.
myAdapter.notifyDataSetChanged(); // notify a change.
listPopupWindow.setWidth(myAdapter.getWidestTextWidth()); // set the width.
listPopupWindow.show(); // show the listpopupwindow-view.
}
}
});
}
});
t.start();
}
@Override
public void afterTextChanged(Editable s) { }
};
}
/**
* Clearing out the listpopupwindow.
*/
private void clearWindow(){
myAdapter.clearData();
myAdapter.notifyDataSetChanged();
listPopupWindow.dismiss();
}
}
\ No newline at end of file
package com.example.laboration3_new;
import java.util.ArrayList;
/**
* Representing the structure of each JSON object. Used with GSON in Fetcher.java.
*/
public class Item {
private String id;
private ArrayList<String> result;
public String getId(){
return id;
}
public ArrayList<String> getResult() {
return result;
}
}
package com.example.laboration3_new;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
private InteractiveSearcher interactiveSearcher;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
interactiveSearcher = findViewById(R.id.interactiveSearcher);
interactiveSearcher.setNumberOfSuggestions(5);
}
}
\ No newline at end of file
package com.example.laboration3_new;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import java.util.ArrayList;
/**
* Adapter for displaying the listpopupwindow. GetView and Row will work hand in hand to
* draw the whole listpopupwindow.
*/
public class MyAdapter extends BaseAdapter {
private Context context;
private ArrayList<String> data; // raw data
public MyAdapter(Context context, ArrayList<String> data) {
this.context = context;
this.data = data;
}
@Override
public int getCount() {
return data.size();
}
@Override
public Object getItem(int position) {
return data.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
/**
* We will create a new Row for each position and return that view, onMeasure/onDraw in Row
* will then draw that row.
*
* @param position The position of the item within the adapter's data set of the item whose view
* we want.
* @param convertView The old view to reuse, if possible. Note: You should check that this view
* is non-null and of an appropriate type before using. If it is not possible to convert
* this view to display the correct data, this method can create a new view.
* Heterogeneous lists can specify their number of view types, so that this View is
* always of the right type (see {@link #getViewTypeCount()} and
* {@link #getItemViewType(int)}).
* @param parent The parent that this view will eventually be attached to
* @return View
*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = new Row(context, data.get(position));
return v;
}
/**
* Setting raw data.
* @param data
*/
public void setData(ArrayList<String> data) {
this.data = data;
}
/**
* Empty out the dataset.
*/
public void clearData(){
this.data.clear();
}
/**
* Check which row is the widest.
* @return maxWidth
*/
public int getWidestTextWidth(){
ArrayList<Row> rows = new ArrayList<>();
for(String suggestion : data){
Row row = new Row(context, suggestion);
rows.add(row);
}
int maxWidth = 0;
for (Row row : rows) {
float textWidth = row.getTextWidth();
maxWidth = (int) Math.max(maxWidth, textWidth);
}
return maxWidth;
}
}
\ No newline at end of file
package com.example.laboration3_new;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import androidx.annotation.Nullable;
/**
* A class representing a single row in the listpopupwindow.
* Main function of this class is to draw that row. With help of onDraw/onMeasure.
*/
public class Row extends View {
private String suggestion;
private Paint paint;
private int textWidth;
public Row(Context context, String suggestion) {
super(context);
paint = new Paint();
paint.setTextSize(40);
this.suggestion = suggestion; // single suggestion.
this.textWidth = (int) paint.measureText(suggestion); // later used in adapter for sizing
// the listpopupwindow.
}
public float getTextWidth(){
return this.textWidth;
}
public Row(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public Row(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public Row(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
canvas.drawText(suggestion, 0, 50, paint);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = View.MeasureSpec.getSize(widthMeasureSpec);
setMeasuredDimension(width, 100);
}
public String getSuggestion(){
return this.suggestion.toString();
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="horizontal">
<com.example.laboration3_new.InteractiveSearcher
android:id="@+id/interactiveSearcher"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment